Docker کے ساتھ VPS پر Supabase خود host کریں
اپنے server پر official Supabase Docker stack چلائیں: %%C9%% میں بدلنے والے secrets، 14 services کا کام، RAM کی ضرورت، backups اور محفوظ updates جانیں۔
آپ کیا تیار کر رہے ہیں
Supabase کی self-hosting کا مطلب ہے کہ official Docker Compose stack کو اپنے server پر چلایا جائے: Postgres، اس کے سامنے REST API، auth service، file storage، realtime websockets، اور Studio dashboard۔ آپ ایک repository کو clone کرتے ہیں، ایک .env file میں ترمیم کرتے ہیں، اور تقریباً 14 containers شروع کرتے ہیں۔ یہ سب مل کر ایک ایسے Supabase project کی طرح کام کرتے ہیں جس کا کنٹرول آپ کے پاس ہوتا ہے۔
Installation مختصر ہے۔ مسئلہ عموماً .env file کی وجہ سے پیدا ہوتا ہے۔ اس میں demo secrets شامل ہوتے ہیں جو repository میں public کیے گئے ہیں، اور ان default values کے ساتھ شروع کیا گیا stack ہر اس شخص کے لیے کھلا ہوتا ہے جو اسے تلاش کر لے۔ یہ guide ان secrets کی وضاحت کرتی ہے جنہیں آپ کو تبدیل کرنا ضروری ہے، ہر service کا مقصد بتاتی ہے، stack کو درکار حقیقی memory کی مقدار بیان کرتی ہے، اور database حذف کیے بغیر اسے update کرنے کا طریقہ دکھاتی ہے۔
اگر Compose آپ کے لیے نیا ہے تو پہلے VPS پر Docker Compose کی بنیادی باتیں پڑھیں۔ ذیل کی تمام ہدایات فرض کرتی ہیں کہ docker compose version پہلے ہی version دکھاتا ہے۔
اسٹیک میں دراصل کیا شامل ہے
Supabase ایک پروگرام نہیں ہے۔ Compose فائل ایک ہی network پر الگ الگ services کا مجموعہ شروع کرتی ہے۔ ہر service کا کردار جاننے سے container names کی لمبی فہرست کو debug کرنا آسان ہو جاتا ہے۔
db، Supabase extensions کے ساتھ PostgreSQL ہے۔ ہر دوسری service اس سے رابطہ کرتی ہے۔ اگر یہ container غیر صحت مند ہو، تو باقی سب services بھی ناکام ہو جاتی ہیں۔kong، API gateway ہے۔ یہ port 8000 پر listening کرتا ہے اور/rest/v1/،/auth/v1/اور/storage/v1/کو درست backend تک route کرتا ہے۔ صرف اسی container کو بیرونی طور پر expose کرنا چاہیے۔rest، PostgREST ہے۔ یہ آپ کے Postgres schema کو پڑھ کر اسے REST API کے طور پر فراہم کرتا ہے۔ اس طرح نئی table بغیر code کے نیا endpoint بن جاتی ہے۔auth، GoTrue ہے۔ یہ JSON web tokens (JWT) جاری کرتا ہے، جو آپ کے users کی شناخت کرتے ہیں۔storageاورimgproxy، file uploads اور image resizing سنبھالتے ہیں۔realtime، database changes کو websockets کے ذریعے stream کرتا ہے۔studioاورmeta، dashboard اور اس کے پیچھے موجود admin API ہیں۔analytics(Logflare) اورvector، logs جمع کرتے ہیں، جبکہsupavisor، Postgres connection pooler ہے۔
اسی وجہ سے نیچے دیے گئے resource numbers اتنے ہیں۔ آپ صرف database نہیں چلا رہے۔ آپ database کے ساتھ ایک درجن support services بھی چلا رہے ہیں۔
سائز بندی: 8 GB RAM کی منصوبہ بندی کریں
جولائی 2026 تک، نئی تنصیب میں، آپ کے اپنے ڈیٹا یا نیٹ ورک ٹریفک کے بغیر، یہ stack عموماً 2.5 سے 3 GB resident memory استعمال کرتا ہے۔ analytics service اور Studio Node.js process سب سے زیادہ memory استعمال کرنے والے دو اجزا ہیں۔ 2 GB والا server containers شروع کر دے گا، لیکن پھر kernel کا out of memory killer ان میں سے ایک کو ختم کر دے گا، عموماً analytics یا db۔ اس کی علامت یہ ہے کہ کوئی container exit code 137 کے ساتھ بار بار restart ہوتا رہے۔
جس کام پر آپ انحصار کرتے ہیں اس کے لیے اسے 8 GB RAM اور 4 vCPU دیں۔ اگر آپ یہ قبول کر سکتے ہیں کہ ایک ہی وقت میں heavy query اور Studio session سست ہوں گے، تو 4 GB تنہا development instance کے لیے کافی ہے۔ Disk بھی اہم ہے، کیونکہ Postgres، storage volume اور log data سب project directory کے اندر محفوظ ہوتے ہیں۔ 40 GB سے شروع کریں اور اس کی نگرانی کریں۔
انسٹال کریں: سرکاری repository کو clone کریں
تجویز کردہ طریقہ main repository سے docker directory کو آپ کی اپنی project directory میں copy کرتا ہے۔ یہ علیحدگی اہم ہے، کیونکہ اس کا مطلب ہے کہ بعد میں چلنے والا git pull آپ کے .env کو overwrite نہیں کر سکے گا۔
git clone --depth 1 https://github.com/supabase/supabase
mkdir supabase-project
cp -rf supabase/docker/* supabase-project
cp supabase/docker/.env.example supabase-project/.env
cd supabase-project
docker compose pulldocker compose pull کئی gigabytes کی images download کرتا ہے۔ اس کے اختتام پر ہر service کا status Pulled ہونا چاہیے۔ یہاں manifest unknown error کا مطلب ہے کہ pinned image tag کو upstream سے ہٹا دیا گیا ہے۔ اس کا حل tags کو ہاتھ سے edit کرنا نہیں، بلکہ repository کی نئی copy pull کرنا ہے۔
پہلی بار شروع کرنے سے پہلے تبدیل کیے جانے والے راز
اسٹیک شروع کرنے سے پہلے یہ کام کریں، بعد میں نہیں۔ ان میں سے کئی اقدار پہلی بار بوٹ ہونے پر ڈیٹا میں لکھی جاتی ہیں، اس لیے بعد میں انہیں تبدیل کرنے کے لیے database کو reset کرنا پڑتا ہے۔
repository میں ایک generator شامل ہے جو ہر قدر درست طور پر تیار کرتا ہے۔ اس میں وہ دو API keys بھی شامل ہیں جن پر آپ کے نئے JWT secret سے دستخط کیے جانے ضروری ہیں۔
sh utils/generate-keys.sh --update-envیہ script JWT_SECRET، ANON_KEY، SERVICE_ROLE_KEY، SECRET_KEY_BASE، REALTIME_DB_ENC_KEY، VAULT_ENC_KEY، PG_META_CRYPTO_KEY اور Logflare tokens کے لیے نئی اقدار .env میں لکھتی ہے۔ اسے openssl درکار ہے، جو کسی بھی عام Ubuntu image میں موجود ہوتا ہے۔
دو اقدار یہ script set نہیں کرتی، اس لیے آپ کو انہیں .env میں دستی طور پر تبدیل کرنا ہوگا:
POSTGRES_PASSWORD۔ صرف حروف اور digits استعمال کریں۔ یہاں punctuation کئی services کے بنائے ہوئے connection strings کو توڑ دیتی ہے، کیونکہ یہ strings کو جوڑ کر تیار کی جاتی ہیں۔ اس کی ناکامی parsing error کے بجائے authentication error جیسی دکھائی دیتی ہے، اس لیے لوگ غلط جگہ مسئلہ تلاش کرتے ہیں۔DASHBOARD_USERNAMEاورDASHBOARD_PASSWORD۔ یہ Studio کے لیے basic authentication credentials ہیں۔ فراہم کردہ default password بعینہٖthis_password_is_insecure_and_should_be_updatedہے۔
سمجھیں کہ ANON_KEY اور SERVICE_ROLE_KEY من گھڑت کیوں نہیں ہو سکتے۔ دونوں JWTs ہیں جن پر JWT_SECRET سے دستخط کیے گئے ہیں۔ gateway ہر request پر اس signature کی تصدیق کرتا ہے، اس لیے آپ کے secret سے مطابقت نہ رکھنے والی key کو {"message":"Invalid authentication credentials"} کے ساتھ مسترد کر دیا جاتا ہے۔ یہ self-hosting کی سب سے عام ناکامی ہے: operator نے JWT_SECRET تبدیل کیا، لیکن demo keys برقرار رکھیں۔ تینوں کو ہمیشہ ایک ساتھ generate کریں۔
SERVICE_ROLE_KEY کو root password کی طرح محفوظ رکھیں۔ یہ row level security کو مکمل طور پر bypass کرتا ہے۔ اسے صرف server side code میں رکھیں، کسی اور جگہ نہیں۔
SITE_URL اور API_EXTERNAL_URL کو اس address پر set کریں جہاں آپ کے users واقعی رسائی حاصل کریں گے، مثلاً https://supabase.example.com۔ Auth انہی اقدار سے اپنی email confirmation اور OAuth callback links بناتا ہے۔ انہیں http://localhost:8000 پر چھوڑنے سے آپ کے ہر user کو اس کی اپنی machine پر بھیج دیا جائے گا۔
اب اپنی ترتیبات چیک کریں:
sh run.sh secretsاسے شروع کریں اور صحت کی تصدیق کریں
sh run.sh start
docker compose psrun.sh start، docker compose up -d --wait کو wrap کرتا ہے، اس لیے health checks کامیاب ہونے تک واپس نہیں آتا۔ ہر service کو running (healthy) یا running دکھانا چاہیے۔ پہلی بار boot ہونے میں دو سے چار منٹ لگتے ہیں، کیونکہ Postgres ابتدائیisation scripts چلاتا ہے، اور اس سے پہلے کوئی چیز connect نہیں کر سکتی۔
اگر کوئی container دوبارہ شروع ہو رہا ہو تو service name کے ذریعے اس کے logs پڑھیں:
docker compose logs db
docker compose logs authاس کے بعد Studio، port 8000 پر دستیاب ہوگا، اور یہ آپ سے وہ dashboard username اور password طلب کرے گا جو آپ نے set کیے ہیں۔
port 8000 کو عوامی انٹرنیٹ پر دستیاب نہ کریں
Kong، port 8000 پر سادہ HTTP استعمال کرتا ہے۔ ہر API key اور ہر صارف کا password نیٹ ورک پر واضح متن میں منتقل ہوتا ہے۔ Studio کی credentials basic authentication استعمال کرتی ہیں، جو encryption کے بجائے base64 encoding ہے۔
اس کے سامنے reverse proxy رکھیں اور وہیں TLS (transport layer security) کو terminate کریں۔ Kong کو loopback address سے bind کریں تاکہ کوئی دوسرا نظام اس تک رسائی نہ حاصل کر سکے۔ docker-compose.yml میں kong port mapping، 127.0.0.1:8000:8000 بن جاتی ہے، اور proxy اسی کو forward کرتا ہے۔ متعدد Compose apps کے سامنے Traefik میں certificate سے متعلق طریقہ بیان کیا گیا ہے۔
باقی ports کو بھی firewall پر بند کریں، کیونکہ Docker اپنے iptables rules لکھ کر ports شائع کرتا ہے، جنہیں سادہ ufw configuration نہیں دیکھتی۔ یہ مسئلہ Docker containers آپ کے ufw rules کو کیوں نظرانداز کرتے ہیں میں بیان کیا گیا ہے۔
ڈائریکٹری کے بجائے ڈیٹابیس کا بیک اپ لیں
Postgres کا ڈیٹا ./volumes/db/data میں bind mount کے طور پر موجود ہے۔ کنٹینر کے چلنے کے دوران اس ڈائریکٹری کو کاپی کرنے سے نامکمل کاپی بنتی ہے، کیونکہ Postgres لکھنے کے عمل کو بفر کرتا ہے اور ڈسک پر موجود فائلیں صرف checkpoint کے وقت مستقل حالت میں ہوتی ہیں۔ اسے بحال کرنا عموماً کامیاب ہو جائے گا، لیکن کبھی کبھار آخری transactions خاموشی سے ضائع ہو جائیں گی۔ بیک اپ کے لیے یہ بدترین ممکنہ failure mode ہے۔
اس کے بجائے dump بنائیں۔ pg_dumpall کنٹینر کے اندر چلتا ہے اور ایک مستقل snapshot بناتا ہے:
docker exec -t supabase-db pg_dumpall -U postgres > supabase-$(date +%F).sqlاس فائل پر اعتماد کرنے سے پہلے تصدیق کریں کہ یہ خالی نہیں ہے۔ پھر مقررہ شیڈول کے مطابق ان dumps کو سرور سے باہر منتقل کریں۔ restic کے ذریعے encrypted offsite backups اسی مقصد کے لیے ہیں۔ اسی وقت اپنے .env کا بھی بیک اپ لیں۔ JWT_SECRET ضائع ہونے سے جاری کیے گئے تمام tokens invalid ہو جائیں گے اور محفوظ کردہ تمام encrypted secrets ناقابلِ مطالعہ ہو جائیں گے۔
اپ لوڈ کی گئی فائلیں ./volumes/storage میں موجود ہوتی ہیں۔ یہ عام فائلیں ہیں، اس لیے سادہ کاپی کافی ہے۔
ڈیٹا ضائع کیے بغیر اپ ڈیٹ
Supabase، docker-compose.yml میں image versions مقرر کرتا ہے، اس لیے جب تک آپ خود اسے اپ ڈیٹ نہیں کرتے، کچھ تبدیل نہیں ہوتا۔ ہر بار پہلے dump لیں۔
docker compose pull
sh run.sh recreaterecreate stack کو روکتا ہے اور نئی images کے ساتھ دوبارہ شروع کرتا ہے۔ آپ کا ڈیٹا محفوظ رہتا ہے کیونکہ یہ containers کے اندر نہیں بلکہ host پر موجود bind mounts میں رہتا ہے۔ بڑے version jump سے پہلے repository میں CHANGELOG.md پڑھیں، کیونکہ Postgres کے major upgrades خودکار نہیں ہوتے اور ان کے لیے dump اور restore درکار ہوتا ہے۔
Compose فائل میں ہونے والی تبدیلیاں حاصل کرنے کے لیے upstream repository کو دوبارہ clone کریں اور اس کی docker directory کو اپنے project میں copy کریں۔ اس دوران .env کو overwrite نہ کریں۔
مکمل reset ایک الگ script کے ذریعے ہوتا ہے۔ یہ database سمیت ہر چیز حذف کر دیتا ہے اور confirmation طلب کرتا ہے:
sh reset.shFAQ
میری API کالز "Invalid authentication credentials" کیوں واپس کرتی ہیں؟
آپ کا ANON_KEY یا SERVICE_ROLE_KEY اس JWT_SECRET کے ساتھ دستخط شدہ نہیں تھا جو فی الحال .env میں موجود ہے۔ گیٹ وے ہر درخواست پر دستخط کی توثیق کرتا ہے اور عدم مطابقت کی صورت میں درخواست مسترد کر دیتا ہے۔ sh utils/generate-keys.sh --update-env کے ذریعے تینوں کو ایک ساتھ دوبارہ بنائیں، پھر sh run.sh recreate چلائیں تاکہ سروسز نئی قدریں پڑھ سکیں۔
کیا میں 2 GB VPS پر self-hosted Supabase چلا سکتا ہوں؟
قابلِ اعتماد طور پر نہیں۔ جولائی 2026 تک یہ stack تقریباً 3 GB میموری استعمال کرتا ہے، کیونکہ یہ تقریباً چودہ سروسز چلاتا ہے۔ اس لیے 2 GB سرور میں out of memory killer کنٹینرز بند کر دیتا ہے، اور آپ کو docker compose ps میں exit code 137 نظر آتا ہے۔ production کے لیے 8 GB استعمال کریں، اور انفرادی development کے لیے 4 GB کو کم از کم حد سمجھیں۔
کیا self-hosted Supabase میں edge functions شامل ہیں؟
جی ہاں۔ Compose فائل میں Deno پر مبنی functions runtime شامل ہے، اور یہ ./volumes/functions کے اندر موجود ہر چیز فراہم کرتا ہے۔ اس میں hosted platform کا عالمی deployment network شامل نہیں ہے، اس لیے آپ کے functions ایک ہی مقام پر، آپ کے ایک سرور پر چلتے ہیں۔
میں Postgres database سے براہِ راست کیسے connect کروں؟
خود سرور پر interactive shell کے لیے docker exec -it supabase-db psql -U postgres استعمال کریں۔ بیرونی client کے لیے port 5432 پر Supavisor کے ذریعے postgres.<POOLER_TENANT_ID> صارف اور اپنے POSTGRES_PASSWORD کے ساتھ connect کریں۔ اس port کو internet کے لیے نہ کھولیں۔ اس تک VPN یا SSH tunnel کے ذریعے رسائی حاصل کریں۔
میری auth confirmation emails میں localhost کا link کیوں آ رہا تھا؟
.env میں SITE_URL اور API_EXTERNAL_URL اپنی default قدروں پر رہ گئے تھے۔ auth service ہر confirmation اور password reset link ان دونوں قدروں سے بناتی ہے، اس لیے وہ وہی address بھیجتی ہے جس پر اسے بھیجنے کے لیے کہا گیا ہو۔ دونوں کو اپنے حقیقی public URL پر سیٹ کریں اور stack دوبارہ بنائیں۔