استضافة Supabase ذاتيًا على VPS باستخدام Docker
شغّل مكدس Supabase الرسمي على خادمك: بدّل الأسرار التجريبية، وافهم الخدمات الأربع عشرة، واحسب الذاكرة المطلوبة، وأنشئ نسخًا احتياطية وحدّثه بأمان.
ما الذي ستبنيه
يعني الاستضافة الذاتية لـ Supabase تشغيل حزمة Docker Compose الرسمية على خادمك الخاص: Postgres، وواجهة REST API أمامه، وخدمة المصادقة، وتخزين الملفات، وWebSockets للتحديث الفوري، ولوحة Studio. تستنسخ مستودعًا واحدًا، وتحرر ملف .env واحدًا، ثم تشغّل نحو أربعة عشر حاوية تعمل معًا مثل مشروع Supabase تتحكم فيه.
عملية التثبيت قصيرة. المشكلة عادةً تكون في ملف .env. يأتي هذا الملف بأسرار تجريبية منشورة في المستودع، وتكون الحزمة التي تبدأ بهذه القيم الافتراضية مفتوحة لأي شخص يعثر عليها. يوضح هذا الدليل الأسرار التي يجب استبدالها، ووظيفة كل خدمة، ومقدار الذاكرة الذي تحتاج إليه الحزمة فعليًا، وكيفية تحديثها دون حذف قاعدة بياناتك.
إذا كانت Compose جديدة عليك، فاقرأ أساسيات Docker Compose على VPS أولًا. يفترض كل ما يلي أن docker compose version يعرض إصدارًا بالفعل.
ما الذي يتضمنه المكدس فعليًا
Supabase ليس برنامجًا واحدًا. يبدأ ملف Compose مجموعة من الخدمات المنفصلة على شبكة واحدة. ومعرفة وظيفة كل خدمة تساعدك على تصحيح الأخطاء بدل التعامل مع قائمة طويلة من أسماء الحاويات.
dbهو PostgreSQL مع تحميل إضافات Supabase. تتصل به جميع الخدمات الأخرى. إذا كانت هذه الحاوية غير سليمة، تفشل جميع الخدمات الأخرى أيضًا.kongهو بوابة API. يستمع على المنفذ 8000 ويوجّه/rest/v1/و/auth/v1/و/storage/v1/إلى الواجهة الخلفية الصحيحة. هذه هي الحاوية الوحيدة التي يجب أن تتيح الوصول إليها من الخارج.restهو PostgREST. يقرأ مخطط Postgres ويقدمه كواجهة REST API، لذلك يتحول أي جدول جديد إلى نقطة نهاية جديدة من دون كتابة تعليمات برمجية.authهو GoTrue. يصدر رموز JSON Web Tokens (JWT) التي تحدد هوية مستخدميك.storageوimgproxyيتوليان تحميل الملفات وتغيير حجم الصور.realtimeيبث تغييرات قاعدة البيانات عبر websockets.studioوmetaهما لوحة المعلومات وواجهة الإدارة API التي تقف خلفها.- يجمع
analytics(Logflare) وvectorالسجلات، بينماsupavisorهو مجمّع اتصالات Postgres.
توضح هذه القائمة سبب كون أرقام الموارد أدناه على ما هي عليه. أنت لا تشغّل قاعدة بيانات فقط. أنت تشغّل قاعدة بيانات مع نحو اثنتي عشرة خدمة مساندة.
تحديد الموارد: خطط لاستخدام 8 GB من ذاكرة RAM
تستخدم الحزمة عند الخمول نحو 2.5 إلى 3 GB من الذاكرة المقيمة في التثبيت الجديد، اعتبارًا من يوليو 2026، قبل إضافة بياناتك أو حركة الشبكة الخاصة بك. تُعد خدمة التحليلات وعملية Studio في Node.js أكبر مستهلكين منفردين للموارد. سيبدأ خادم بسعة 2 GB تشغيل الحاويات، ثم يفقد إحداها بسبب قاتل نفاد الذاكرة في النواة، وعادةً ما تكون analytics أو db. وتتمثل الأعراض في بقاء حاوية قيد إعادة التشغيل مع رمز الخروج 137.
خصص 8 GB من ذاكرة RAM و4 vCPU لأي استخدام تعتمد عليه. تعمل سعة 4 GB مع مثيل تطوير فردي إذا قبلت بأن الاستعلامات الثقيلة وجلسة Studio في الوقت نفسه ستكون بطيئة. مساحة القرص مهمة أيضًا، لأن Postgres ووحدة التخزين وبيانات السجل توجد جميعًا ضمن مجلد المشروع. ابدأ بسعة 40 GB وراقب الاستخدام.
التثبيت: استنسخ المستودع الرسمي
ينسخ المسار المدعوم الدليل docker من المستودع الرئيسي إلى دليل مشروع تملكه. يفصل ذلك بينهما، لأن git pull لاحقًا لن يتمكن من الكتابة فوق .env.
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 pullينزّل docker compose pull عدة غيغابايت من الصور. يجب أن ينتهي مع وضع علامة Pulled على كل خدمة. يشير خطأ manifest unknown هنا إلى أن وسم الصورة المثبت أزيل من المستودع الأصلي، والحل هو سحب نسخة أحدث من المستودع بدلًا من تعديل الوسوم يدويًا.
الأسرار التي يجب تغييرها قبل التشغيل الأول
نفّذ ذلك قبل بدء تشغيل المكدس، وليس بعده. تُكتب عدة قيم من هذه القيم في البيانات عند التشغيل الأول، لذا يعني تغييرها لاحقًا إعادة ضبط قاعدة البيانات.
يتضمن المستودع مولّدًا يُنشئ كل قيمة بشكل صحيح، بما في ذلك مفتاحي API اللذين يجب توقيعهما باستخدام سر JWT الجديد.
sh utils/generate-keys.sh --update-envيكتب هذا البرنامج النصي قيمًا جديدة لـ JWT_SECRET وANON_KEY وSERVICE_ROLE_KEY وSECRET_KEY_BASE وREALTIME_DB_ENC_KEY وVAULT_ENC_KEY وPG_META_CRYPTO_KEY ورموز Logflare المميزة داخل .env. ويحتاج إلى openssl، وهو متوفر في أي صورة Ubuntu عادية.
لا يضبط البرنامج النصي قيمتين، ويجب تعديلهما يدويًا في .env:
POSTGRES_PASSWORD. استخدم الأحرف والأرقام فقط. تؤدي علامات الترقيم هنا إلى كسر سلاسل الاتصال التي تنشئها عدة خدمات عبر ضم السلاسل. ويظهر الفشل كأنه خطأ في المصادقة، وليس خطأ في التحليل، ما يدفع إلى البحث في المكان الخطأ.DASHBOARD_USERNAMEوDASHBOARD_PASSWORD. هاتان هما بيانات اعتماد المصادقة الأساسية لـ Studio. كلمة المرور الافتراضية المضمّنة هي حرفيًاthis_password_is_insecure_and_should_be_updated.
افهم سبب عدم إمكانية اختلاق ANON_KEY وSERVICE_ROLE_KEY. فكلاهما JWT موقّع باستخدام JWT_SECRET. تتحقق البوابة من هذا التوقيع في كل طلب، لذلك يُرفض المفتاح الذي لا يطابق سرك مع {"message":"Invalid authentication credentials"}. هذا هو أكثر أعطال الاستضافة الذاتية شيوعًا: يغيّر المشغّل JWT_SECRET لكنه يُبقي مفاتيح العرض التجريبي. أنشئ القيم الثلاث معًا دائمًا.
تعامل مع SERVICE_ROLE_KEY مثل كلمة مرور root. فهو يتجاوز أمان مستوى الصف بالكامل. يجب أن يوجد في التعليمات البرمجية على جانب الخادم فقط، وليس في أي مكان آخر.
اضبط SITE_URL وAPI_EXTERNAL_URL على العنوان الذي سيصل إليه المستخدمون فعليًا، مثل https://supabase.example.com. ينشئ Auth روابط تأكيد البريد الإلكتروني وعمليات استدعاء OAuth من هذه القيم، لذلك يؤدي إبقاؤها على http://localhost:8000 إلى إرسال كل مستخدم من مستخدميك إلى جهازه الخاص.
ثم تحقّق من القيم الحالية:
sh run.sh secretsشغّله وتحقّق من سلامته
sh run.sh start
docker compose psيغلّف run.sh start الأمر docker compose up -d --wait، لذلك لا يعيد النتيجة حتى تنجح فحوصات السلامة. يجب أن تعرض كل خدمة running (healthy) أو running. يستغرق التشغيل الأول من دقيقتين إلى أربع دقائق، لأن Postgres يشغّل نصوص التهيئة قبل أن يتمكن أي شيء آخر من الاتصال.
إذا كانت إحدى الحاويات تعيد التشغيل، فاقرأ سجلاتها باستخدام اسم الخدمة:
docker compose logs db
docker compose logs authيعمل Studio بعد ذلك على المنفذ 8000، وسيطلب اسم مستخدم لوحة المعلومات وكلمة المرور اللذين عيّنتهما.
لا تضع المنفذ 8000 على الإنترنت العام
يتحدث Kong على المنفذ 8000 باستخدام HTTP العادي. تنتقل كل مفاتيح API وكل كلمات مرور المستخدمين عبر الشبكة بنص واضح. وتعتمد بيانات اعتماد Studio على المصادقة الأساسية، وهي ترميز base64 وليست تشفيرًا.
ضع وكيلًا عكسيًا أمامه، وأنهِ TLS (أمان طبقة النقل) عنده، واربط Kong بعنوان loopback حتى لا يتمكن أي شيء آخر من الوصول إليه. في docker-compose.yml يصبح تعيين المنفذ kong هو 127.0.0.1:8000:8000، ثم يوجّه الوكيل الطلبات إلى ذلك المنفذ. يشرح Traefik أمام عدة تطبيقات Compose جانب الشهادات.
أغلق بقية المنافذ في جدار الحماية أيضًا، لأن Docker ينشر المنافذ بكتابة قواعد iptables الخاصة به، ولا ترى إعدادات ufw الساذجة هذه القواعد مطلقًا. يشرح سبب تجاهل حاويات Docker لقواعد ufw هذا الفخ.
انسخ قاعدة البيانات احتياطيًا، وليس الدليل
توجد بيانات Postgres في نقطة ربط bind mount عند ./volumes/db/data. يؤدي نسخ هذا الدليل أثناء تشغيل الحاوية إلى إنشاء نسخة غير متسقة، لأن Postgres يخزن الكتابات مؤقتًا، ولا تكون الملفات على القرص متسقة إلا عند نقطة تحقق. ستنجح استعادة هذه النسخة عادةً، لكنها قد تفقد آخر المعاملات دون تنبيه. وهذا أسوأ نمط فشل ممكن للنسخ الاحتياطي.
استخدم التفريغ بدلًا من ذلك. يعمل pg_dumpall داخل الحاوية وينشئ لقطة متسقة:
docker exec -t supabase-db pg_dumpall -U postgres > supabase-$(date +%F).sqlتحقق من أن الملف غير فارغ قبل الاعتماد عليه. ثم انقل ملفات التفريغ خارج الخادم وفق جدول زمني. وهذا ما توفره النسخ الاحتياطية المشفرة خارج الموقع باستخدام restic. أنشئ نسخة احتياطية من .env في الوقت نفسه. يؤدي فقدان JWT_SECRET إلى إبطال كل رمز مميز تم إصداره، ويجعل كل سر مشفر مخزن غير قابل للقراءة.
توجد الملفات المرفوعة في ./volumes/storage. وهذه ملفات عادية، لذا يكفي نسخها بالطريقة المعتادة.
التحديث دون فقدان البيانات
يثبّت Supabase إصدارات الصور في docker-compose.yml، لذلك لا يتغير شيء حتى تنفّذ التحديث. أنشئ نسخة تفريغ أولًا في كل مرة.
docker compose pull
sh run.sh recreateيوقف recreate المكدس ثم يعيد تشغيله باستخدام الصور الجديدة. تبقى بياناتك محفوظة لأنها موجودة في عمليات الربط من المضيف، وليس داخل الحاويات. اقرأ CHANGELOG.md في المستودع قبل الانتقال إلى إصدار رئيسي جديد، لأن ترقيات Postgres الرئيسية ليست تلقائية وتتطلب إنشاء نسخة تفريغ ثم استعادتها.
لتطبيق التغييرات على ملف Compose نفسه، استنسخ المستودع المنبع مرة أخرى وانسخ دليل docker منه إلى مشروعك، مع الحرص على عدم الكتابة فوق .env.
إعادة الضبط الكاملة، التي تحذف كل شيء بما في ذلك قاعدة البيانات، تتم بواسطة برنامج نصي منفصل ويطلب تأكيدًا:
sh reset.shFAQ
لماذا تعيد استدعاءات API لديّ الرسالة "بيانات اعتماد المصادقة غير صالحة"؟
لم يتم توقيع ANON_KEY أو SERVICE_ROLE_KEY باستخدام JWT_SECRET الموجود حاليًا في .env. تتحقق البوابة من التوقيع في كل طلب، وترفض الطلب عند عدم التطابق. أعد إنشاء القيم الثلاث معًا باستخدام sh utils/generate-keys.sh --update-env، ثم شغّل sh run.sh recreate لكي تقرأ الخدمات القيم الجديدة.
هل يمكنني تشغيل Supabase مستضاف ذاتيًا على VPS بسعة 2 GB؟
ليس بشكل موثوق. يستهلك المكدس نحو 3 GB عند الخمول اعتبارًا من July 2026، لأنه يشغّل نحو أربعة عشر خدمة. لذلك يفقد الخادم بسعة 2 GB الحاويات بسبب قاتل نفاد الذاكرة، وتظهر لك شيفرة الخروج 137 في docker compose ps. استخدم 8 GB في بيئة الإنتاج، واعتبر 4 GB الحد الأدنى للتطوير الفردي.
هل يتضمن Supabase المستضاف ذاتيًا الدوال الطرفية؟
نعم. يتضمن ملف Compose بيئة تشغيل الدوال المعتمدة على Deno، ويخدم أي محتوى تضعه ضمن ./volumes/functions. لكنه لا يتضمن شبكة النشر العالمية للمنصة المستضافة. لذلك تعمل دوالك على خادمك الوحيد وفي موقع واحد.
كيف أتصل بقاعدة بيانات Postgres مباشرة؟
استخدم docker exec -it supabase-db psql -U postgres لفتح جلسة تفاعلية على الخادم نفسه. للاتصال من عميل خارجي، اتصل عبر Supavisor على المنفذ 5432 باستخدام المستخدم postgres.<POOLER_TENANT_ID> وPOSTGRES_PASSWORD الخاص بك. لا تفتح هذا المنفذ على الإنترنت. اتصل به عبر VPN أو نفق SSH.
لماذا كانت روابط رسائل تأكيد المصادقة تشير إلى localhost؟
تم ترك SITE_URL وAPI_EXTERNAL_URL في .env على القيم الافتراضية. تبني خدمة المصادقة كل رابط لتأكيد الحساب وإعادة تعيين كلمة المرور من هاتين القيمتين، ولذلك ترسل العنوان الذي أُعطيت لها. عيّن القيمتين إلى عنوان URL العام الحقيقي لديك، ثم أعد إنشاء المكدس.