لماذا تستضيف Supabase ذاتيًا على VPS
Supabase ليس صندوقًا أسود: إنه مجموعة من الخدمات مفتوحة المصدر (PostgreSQL، وGoTrue للمصادقة، وPostgREST للواجهة البرمجية، وRealtime، وStorage، وEnvoy كبوابة بعد Kong سابقًا) مُنسَّقة معًا. تُفوتر النسخة السحابية لكل مشروع ولكل مستخدم نشط شهريًا، وتوقف المشاريع المجانية الخاملة. باستضافة Supabase ذاتيًا على خادم VPS، تحصل على backend-as-a-service متكامل دون هذه القيود، مع وصول مباشر إلى PostgreSQL للهجرات والإضافات (pgvector، PostGIS) والضبط. مثالي لوكالة تستضيف تطبيقات عدة لعملاء، أو SaaS ناشئ يريد التحكم في التكاليف، أو أي مشروع يستلزم سيادة البيانات. تدير التحديثات والنسخ الاحتياطية بنفسك، مقابل حرية كاملة.
المزايا الملموسة لـ Supabase المستضاف ذاتيًا
- backend متكامل: Postgres والمصادقة والتخزين وRealtime وواجهة REST/GraphQL في مكدس واحد.
- وصول مباشر إلى PostgreSQL الأساسي: هجرات SQL وإضافات وسياسات RLS بلا حدود.
- بلا إيقاف مؤقت أو فوترة لكل مستخدم نشط شهريًا.
- Studio مضمَّن: واجهة ويب للإدارة لإدارة الجداول والمصادقة والـbuckets.
- إضافات الذكاء الاصطناعي عبر
pgvectorللـRAG والبحث الدلالي، مفعَّلة بحرية. - مشاريع متعددة على نفس الـ VPS: عملي لوكالة أو استوديو تطوير.
متطلبات الأجهزة والبرامج
يشغّل Supabase المستضاف ذاتيًا نحو عشر حاويات (Postgres، وEnvoy، وGoTrue، وPostgREST، وRealtime، وStorage، وStudio، وMeta، وImgproxy...)، مما يجعله أكثر استهلاكًا من قاعدة بيانات بسيطة. احسب حدًا أدنى من 2 vCPU و4 غيغابايت RAM لبيئة تجريبية، ويُفضَّل 4 vCPU مع 8 غيغابايت RAM و80 غيغابايت SSD للإنتاج. على صعيد البرامج: Ubuntu 22.04/24.04 LTS، وDocker وDocker Compose v2، واسم نطاق يشير إلى الخادم (مثلاً api.myapp.com) لعرض البوابة بصيغة HTTPS، وبروكسي عكسي مثل Caddy أو Traefik أو Nginx لإدارة SSL. خطِّط أيضًا لتوليد أسرار قوية (JWT_SECRET، مفاتيح anon وservice_role).
نشر Supabase المستضاف ذاتيًا بـ Docker
استنساخ المستودع الرسمي وإعداد البيئة
احصل على مجلد
dockerمن مستودع Supabase، وانسخ.env.exampleإلى.env، ثم أنشئ أسرارًا فريدة:POSTGRES_PASSWORD، وJWT_SECRET، ومفاتيحANON_KEY/SERVICE_ROLE_KEYالمشتقة من JWT. لا تنشر أبدًا بالقيم الافتراضية.تهيئة عناوين URL وكلمة مرور Studio
في
.env، عيِّنSITE_URLوAPI_EXTERNAL_URLوSUPABASE_PUBLIC_URLبنطاقك، وحمِّ Supabase Studio بـDASHBOARD_USERNAMEوDASHBOARD_PASSWORD: يمنح Studio وصولًا إداريًا كاملًا لمشروعك.تشغيل المكدس
ابدأ بـ
docker compose up -d، ثم تابع بدء تشغيل الخدمات عبرdocker compose ps. تستغرق التهيئة الأولى لـPostgres وتطبيق هجرات داخلية دقيقة إلى دقيقتين؛ تحقق من غياب الأخطاء فيdocker compose logs.وضع بروكسي عكسي مع SSL
ضع Caddy أو Traefik أمام بوابة الـ API (Envoy، المنفذ 8000) لعرض واجهتك البرمجية بصيغة HTTPS. يحصل Caddy على شهادات Let's Encrypt ويجدِّدها تلقائيًا: كتلة بسيطة
myapp.com { reverse_proxy localhost:8000 }تكفي. لا تكشف Postgres للعموم أبدًا. غير أن ملف compose الرسمي ينشر البوابة (8000) ومجمّع الاتصالات Supavisor (5432 و6543) على كل الواجهات، والمنافذ التي ينشرها Docker تتجاوز ufw: أضف قبلها127.0.0.1:فيdocker-compose.yml(مثلًا127.0.0.1:${POSTGRES_PORT}:5432)، أو أغلقها في الجدار الناري لدى مزوّدك.تفعيل سياسات RLS
اتصل بـStudio، وأنشئ جداولك، ثم فعِّل Row Level Security على كل منها وعرِّف سياساتك. بدون RLS، يكشف مفتاحك
anonجميع بياناتك: هذا الإعداد الواجب قبل عرض أي شيء.نسخ Postgres والتخزين احتياطيًا
جدوِل
pg_dumpيوميًا لقاعدة البيانات، وأرشف حجم التخزين (مجلدات الملفات) إلى تخزين خارجي. اختبر الاستعادة الكاملة على VPS تجريبي قبل الاعتماد عليها في الإنتاج.
Supabase أم Appwrite: أيّ BaaS مستضاف ذاتيًا تختار؟
مرّر الجدول أفقيًا
| المعيار | Supabase | Appwrite |
|---|---|---|
| قاعدة البيانات | PostgreSQL أصيل، SQL كامل | MariaDB داخليًا، واجهة وثيقة/مجموعة |
| نموذج البيانات | علائقي، RLS Postgres | وثائق ومجموعات، صلاحيات بقاعدة |
| واجهة برمجية تلقائية | REST (PostgREST) + GraphQL | REST وGraphQL ومجموعات SDK متعددة |
| المصادقة | GoTrue وOAuth وروابط سحرية | مصادقة مدمجة وOAuth وفرق وJWT |
| بصمة الموارد | أثقل (~10 حاويات) | معتدلة، مكدس أكثر إحكامًا |
| البحث الشعاعي/الذكاء الاصطناعي | أصيل عبر pgvector | غير أصيل، يجب الاستعانة بخارجي |
| الأنسب لـ | تطبيقات علائقية، RAG، SQL متقدم | تطبيقات جوال/ويب موجَّهة للوثائق |
| منحنى التعلم | مريح إن أتقنت SQL | سريع لمطوري الواجهة الأمامية/الجوال |
حدِّث Supabase بحذر: إذ إن الصور مُرقَّمة في docker-compose.yml، نفِّذ دائمًا pg_dump كاملًا ولقطة للخادم قبل docker compose pull && docker compose up -d. بعض التحديثات تمس مخطط الخدمات الداخلية. للإنتاج، عزل Postgres على حجم مخصص عالي IOPS، واعلم أن pgvector مضمَّن في الصورة: يمكن تفعيله في أي وقت بـ create extension vector; دون إعادة بناء القاعدة.
انشر من المكدس الرسمي لـ Supabase، لا من compose محلي الصنع
قد يبدو إغراؤك في كتابة docker-compose مُختزَل بالخدمات التي تحتاجها وحسب. في الواقع، هذا يتعطّل: تنفِّذ صورة supabase/postgres نصها الخاص للهجرة (migrate.sh) الذي يُنشئ الأدوار الأساسية (supabase_admin، authenticator، supabase_auth_admin...) ومخطط المصادقة بالكامل، وتتوقع وجود ملفات SQL لتهيئة Supabase مرفوعة كملفات مع توسيع المتغيرات وقت التشغيل. لا يمكن لـcompose داخلي مستقل استنساخ ذلك (يُفسِّر Docker Compose المتغيرات داخل الإعدادات الداخلية، تاركًا مخطط المصادقة نصف مهاجَر وGoTrue يفشل بـ'must be owner of function auth.uid()'). المقاربة الصلبة — تلك التي يستخدمها ServOrbit — هي نشر ملفات Docker الرسمية لـSupabase، مثبَّتة على إصدار محدد، وترك migrate.sh يُشغِّل الإقلاع تمامًا كما يتوقعه upstream.
النسخ الاحتياطي التلقائي لنسختك
لا ينشئ نشر Supabase عبر Docker أي نسخة احتياطية من تلقاء نفسه، وهذه أكثر ثغرة يبلّغ عنها من يستضيفونه ذاتيًا. تتكامل آليتان. الأولى، pg_dump، تنتج نسخة منطقية كاملة: شغّلها من المضيف عبر cron، واكتبها إلى وحدة تخزين منفصلة عن وحدة قاعدة البيانات، واحتفظ بعدة أجيال منها. والثانية، أرشفة WAL، تسجّل كل معاملة وتتيح الرجوع إلى لحظة محددة بدل الرجوع إلى آخر نسخة. الأولى تكفي معظم المشاريع، والثانية تصبح ضرورية حين يكون فقدان يوم من الكتابات غير مقبول. وفي الحالتين، لا تساوي النسخة الاحتياطية شيئًا قبل أن تثبت الاستعادة صحتها: أنشئ نسخة فارغة وأعد تشغيل ملف النسخ داخلها قبل أن تحتاج إليها فعلًا.
تخفيف الحزمة: خدمة التحليلات
حتى الإصدار المستضاف ذاتيًا 0.5.0 (يونيو 2026)، كانت تركيبة Docker الرسمية تضمّ Logflare، خدمة التحليلات الداخلية في Supabase، باسم analytics. أصبحت الآن اختيارية: أُزيلت من docker-compose.yml الافتراضي، وتُفعَّل عبر الملف الإضافي docker-compose.logs.yml. ليست ضرورية للواجهة البرمجية ولا للمصادقة ولا للتخزين: إنها أداة مراقبة. في نسخة أقدم قد تكون ما زالت تعمل، وعلى VPS محدود الموارد كثيرًا ما تظهر بحالة unhealthy دون أن يتأثر باقي المكدس. قِس أولًا ما تستهلكه لديك بـ docker stats قبل أن تقرر: إن كانت مراقبتك تمر أصلًا بأداة خارجية فلن تخسر شيئًا، وإن كنت تعتمد على سجلاتها فلا توقفها إلا بعد ربط بديل.
الانتقال من Kong إلى Envoy: ما الذي يتغيّر، ولمن يُعدّ كاسرًا
في 11 أغسطس 2026، مع الإصدار المستضاف ذاتيًا 0.8.0، جعلت Supabase من Envoy بوّابة الـ API الافتراضية للتنصيبات المستضافة ذاتيًا، وانتقل Kong إلى طبقة اختيارية. كان Envoy متاحًا منذ عدّة إصدارات عبر docker-compose.envoy.yml — الذي تغيّر هو الافتراضي.
في docker-compose.yml صارت الخدمة تُسمّى api-gw والحاوية supabase-envoy، لكن الاسم الشبكي البديل kong باقٍ: الخدمات التي تنادي البوّابة بهذا الاسم تستمر في العمل. ويبقى منفذ HTTP هو 8000، ويُضبط عبر API_GW_HTTP_PORT، فلا يحتاج وسيطك العكسي Caddy أو Nginx إلى أي تعديل.
⚠️ تصف Supabase هذا التغيير بأنه كاسر لجزء من المستضيفين ذاتيًا، وعليك معرفة إن كنت منهم. ثلاث حالات: كنت تعتمد على منفذ HTTPS 8443 المدمج في Kong — لم يعد مُتاحًا بالافتراضي، وانتقلت إنهاء TLS إلى docker-compose.caddy.yml أو docker-compose.nginx.yml؛ كان لديك volumes/api/kong.yml مُخصَّص — يجب نقل المسارات والإضافات إلى إعداد Envoy في volumes/api/envoy/؛ تشير نصوصك إلى البوابة باسم الخدمة. في الحالات الثلاث يمكنك البقاء على Kong: sh run.sh config add kong.
الانتقال إلى Envoy دون كسر بوّابتك
معرفة ما تشغّله حاليًا
شغِّل
docker compose ps. وجود حاويةsupabase-kongيعني أنك لا تزال على Kong؛supabase-envoyيعني أن التحويل تمّ. تحقق أيضًا من وجودvolumes/api/kong.ymlمُعدَّل عن نسخة المستودع — هو الذي يقرر ما إذا كان الانتقال يستلزم عملًا منك.النسخ الاحتياطي قبل لمس الـcompose
خذ
pg_dumpكاملًا، وإن سمح مزوِّد الخدمة، لقطة للخادم. التبديل بين البوابتين لا يمسّ مخطط PostgreSQL، لكنه يغير مسار دخول جميع الطلبات: العودة السريعة للخلف أفضل من التشخيص على الهواء.القرار: نقل أم بقاء
إن كان
kong.ymlالخاص بك هو نفسه في المستودع، فلا شيء لنقله. إن احتوى على مسارات أو إضافات خاصة بك، ثمة مسلكان: ترجمتها إلى إعداد Envoy فيvolumes/api/envoy/، أو البقاء على Kong معsh run.sh config add kongريثما تُنجز الأمر. البقاء قرار مشروع، وليس فشلًا.سحب الـcompose الجديد وإعادة التشغيل
اسحب أحدث نسخة من مجلد
dockerفي المستودع الرسمي لـSupabase، ثمdocker compose down && docker compose up -d. تحقق من أنapi-gwيصل إلىhealthyوأن واجهة البرمجة تستجيب على المنفذ 8000.إعادة TLS إن كنت تستخدم 8443 من Kong
منفذ HTTPS المدمج لم يعد مُتاحًا. أضف إنهاء TLS بـ
docker-compose.caddy.ymlأوdocker-compose.nginx.yml، أو اتركه للوسيط العكسي الموجود أمام المنفذ 8000. هذه النقطة هي الأكثر تعطلًا، ولا تظهر إلا عند أول استدعاء HTTPS مباشر.التحقق من التخزين وعناوين URL الموقَّعة
اختبر تنزيلًا من حاوية خاصة عبر URL مُوقَّع مسبقًا. إن حصلت على 403 بعد التبديل، انظر أولًا إلى إعادة كتابة رأس
Hostوقيمة URL العامة لخدمة التخزين: هناك يكمن الفارق بين البوابتين.
Kong وEnvoy نقطة بنقطة
مرّر الجدول أفقيًا
| الجانب | Kong (قبل أغسطس 2026) | Envoy (الافتراضي منذ) |
|---|---|---|
| الخدمة في `docker-compose.yml` | `kong` | `api-gw` — الاسم الشبكي `kong` محفوظ |
| الحاوية | `supabase-kong` | `supabase-envoy` |
| منفذ HTTP | 8000 | 8000 — عبر `API_GW_HTTP_PORT` |
| منفذ HTTPS المدمج | 8443 | **مُزال** — TLS عبر `docker-compose.caddy.yml` / `.nginx.yml` |
| الإعداد | `volumes/api/kong.yml` | `volumes/api/envoy/` (YAML مُصدَّر) |
| العودة لـKong | — | `sh run.sh config add kong` |
CVE-2026-31813: ثغرة OIDC في GoTrue — حدِّث الآن
نُشرت في مارس 2026 ثغرة في GoTrue (Supabase Auth، خدمة المصادقة في Supabase) تحت المرجع CVE-2026-31813. وهي تمسّ تسجيل الدخول برمز ID token لدى مزوّدَي Apple وAzure: كان GoTrue يتحقق من الرمز لدى الجهة المُصدِرة التي يحددها الرمز نفسه، بما في ذلك جهة يتحكم فيها المهاجم.
عمليًا، المهاجم الذي يوقّع من جهة OIDC خاصة به رمز ID token يحمل عنوان البريد الإلكتروني لضحية يحصل على جلسة صالحة (بمستوى AAL1) على حساب هذه الضحية. لا تتأثر إلا النسخ التي فُعِّل فيها مزوّد Apple أو Azure. أما النسخ التي تكتفي بالمصادقة بالبريد الإلكتروني وكلمة المرور أو بالروابط السحرية فهي غير معرَّضة.
الإصلاح مضمَّن في Supabase Auth (GoTrue) 2.185.0. للتحقق من إصدارك: docker compose exec auth gotrue version. إذا كان إصدار gotrue لديك أقدم من 2.185.0، فحدِّث فورًا.
تحديث GoTrue لإصلاح CVE-2026-31813
تحديد الإصدار الحالي
من مجلد مكدس Supabase الخاص بك:
docker compose exec auth gotrue version. إن أظهرت النتيجة إصدارًا < 2.185.0، فنسختك مكشوفة لـCVE-2026-31813. سجِّل أيضًا إصدار المكدس العام:grep 'SUPABASE_VERSION' .env(إن ثبَّته) أوdocker compose images | grep supabase.النسخ الاحتياطي قبل التحديث
قبل أي تحديث، انسخ قاعدة البيانات:
(umask 077; docker compose exec -T db pg_dumpall -h localhost -U supabase_admin > /root/supabase-backup-$(date +%F).sql)، وليس أبدًا في/tmpالذي يقرؤه كل حساب على الخادم. تحديث GoTrue لا يستلزم هجرة مخطط PostgreSQL، لكن النسخة الاحتياطية المسبقة تبقى قاعدة قبل أي تغيير في إصدار بيئة الإنتاج.التحديث إلى Supabase Auth 2.185.0 أو أحدث
في
docker-compose.yml، حدِّث علامة صورةsupabase/gotrueإلىv2.185.0أو أحدث، أو إن كنت تتبع المكدس الكامل، اسحب آخر إصدار متوافق:docker compose pull && docker compose up -d auth. تحديث GoTrue وحده لا يستلزم إعادة تشغيل الخدمات الأخرى. تحقق بـdocker compose exec auth gotrue versionمن تفعيل الإصدار الجديد.التحقق من مصادقة OIDC
بعد التحديث، اختبر تدفق مصادقة كاملًا مع كل مزوِّد OIDC مُهيَّأ: تسجيل دخول، خروج، إعادة دخول. تحقق في سجلات GoTrue (
docker compose logs auth) من غياب رسائل خطأ متعلقة بالتحقق منissفي ظروف الاستخدام الطبيعي.
تعطيل Apple وAzure مؤقتًا إن تعذَّر التحديث فورًا
إن تعذّر التحديث الفوري (لأنه يتطلب نافذة صيانة)، قلّل سطح التعرّض بتعطيل مزوّدَي Apple وAzure مؤقتًا. في الاستضافة الذاتية يُضبطان عبر متغيرات البيئة لخدمة auth: اجعل GOTRUE_EXTERNAL_APPLE_ENABLED وGOTRUE_EXTERNAL_AZURE_ENABLED بقيمة false، ثم شغّل docker compose up -d auth. تبقى المصادقة بالبريد الإلكتروني وكلمة المرور تعمل. هذا الحل مؤقت: لا يصلح الثغرة، بل يقلّل سطح الهجوم فقط ريثما تُعدّ التحديث.
هجرة PostgreSQL 15 ← 17: ثبِّت الإصدار قبل أي سحب
في 17 يونيو 2026، ومع الإصدار المستضاف ذاتيًا 0.6.0، غيّرت Supabase صورة PostgreSQL الافتراضية في ملف docker-compose.yml الرسمي من الإصدار 15 إلى الإصدار 17 (وهو تغيير أُعلن في 18 مايو 2026 في النقاش [#46080](https://github.com/orgs/supabase/discussions/46080)). هذا التغيير مدمِّر إن تجاهلته: تحذّر الجهة المطوّرة من تشغيل PostgreSQL 17 أبدًا على مجلد بيانات أنشأه PostgreSQL 15. وسحب ملف compose الجديد دون احتياط على نسخة ما زالت على PG 15 يعرّضك لقاعدة لا تعود تقلع.
الفخ الثاني: الإضافات timescaledb وplv8 وplcoffee وplls غير مبنية لصورة PG 17. لا تُثبَّت أيّ منها افتراضيًا؛ وإن أضفت إحداها وتحتاج إلى الاحتفاظ بها، فتنصح الجهة المطوّرة بعدم إطلاق الترقية. تحقّق قبل المتابعة: docker compose exec db psql -U postgres -c "\dx" يسرد الإضافات المفعّلة.
الهجرة من PostgreSQL 15 إلى 17 دون فقدان بياناتك
البقاء على PG 15 قبل أي `docker compose pull`
تحقّق أولًا من إصدارك:
docker compose exec db psql -U postgres -c "SELECT version();". إن كان يبدأ بـ 15، فاحتفظ بصورة PG 15 ما دامت الهجرة لم تتم: يوفّر المستودع الملف الإضافيdocker-compose.pg15.ymlالذي يثبّتsupabase/postgres:15.8.1.085. أضفه بـsh run.sh config add pg15، أو مرّره يدويًا:docker compose -f docker-compose.yml -f docker-compose.pg15.yml up -d. وهو أيضًا هدف التراجع لسكربت الهجرة.نسخ البيانات ومفتاح pgsodium احتياطيًا
في صدفة root، ابدأ بـ
umask 077: لن تكون الملفات المُنشأة مقروءة إلا لك. انسخ مجلد البيانات:cp -a ./volumes/db/data ./volumes/db/data-manual-backup. ثم احفظ مفتاح الجذر pgsodium، المخزَّن في وحدة Docker المسماةdb-configلا في هذا المجلد:docker compose run --rm db cat /etc/postgresql-custom/pgsodium_root.key > ./pgsodium_root.key.backup. من دونه تصبح أسرار Vault غير قابلة للاسترجاع. وإضافة إلى ذلك، تصدير منطقي:docker compose exec -T db pg_dumpall -h localhost -U supabase_admin > ./pg15_dump.sql. انسخ هذه الملفات إلى تخزين خارجي.التحقق من الإضافات ومساحة القرص
docker compose exec db psql -U postgres -c "\dx"يسرد الإضافات المفعّلة. إن ظهرتtimescaledbأوplv8أوplcoffeeأوpllsوكنت بحاجة إليها، فتوقّف هنا: لا وجود لها في PG 17. وإلا فسيقترح عليك السكربت حذفها. تحقّق أيضًا من المساحة الحرة: يلزم ضعف حجم القاعدة على الأقل، مضافًا إليه 5 غيغابايت.جلب مجلد docker المحدَّث
اسحب أحدث نسخة من مجلد
dockerفي مستودع Supabase الرسمي، وهو يحتوي علىutils/upgrade-pg17.sh. اترك كل حاويات المكدس قيد التشغيل: السكربت يشترط ذلك. لا تحذف أي وحدة Docker يدويًا، وخصوصًاdb-configالتي تحمل مفتاح pgsodium.تشغيل الهجرة الرسمية
sudo bash utils/upgrade-pg17.sh. يوقف السكربت المكدس، ويشغّلpg_upgradeمن حاوية PG 15 مؤقتة، ويعيد تفعيل الإضافات في حاوية PG 17، ويبدّل مجلدات البيانات مع الاحتفاظ بالأصل في./volumes/db/data.bak.pg15، ثم يعيد تشغيل Supabase على PG 17. ويطلب التأكيد عند كل خطوة مهمة (--yesلتجاوز ذلك).التحقق ثم التنظيف
تحقّق من الإصدار بـ
docker compose exec db psql -U postgres -c "SELECT version();"، ثمdocker compose ps، واختبر استدعاء API كاملًا. إن كانdocker-compose.pg15.ymlما زال مدرجًا فيCOMPOSE_FILE، فأزله بـsh run.sh config remove pg15. وبعد التحقق من كل شيء فقط، احذف./volumes/db/data.bak.pg15و./volumes/db/pgsodium_root.key.bak.pg15والأرشيف./volumes/db/pg17_upgrade_bin_*.tar.gzلاستعادة المساحة.