لماذا تستضيف Appwrite ذاتيًا على خادم VPS
يجمع Appwrite في منصّة واحدة كل ما يحتاجه التطبيق من جانب الخادم: مصادقة بأكثر من 30 طريقة OAuth، وقاعدة بيانات وثائقية بصلاحيات دقيقة، وتخزين ملفات مع تحويل الصور، ووظائف serverless بعدة لغات، ومراسلة. تفرض نسخته السحابية الفوترة حسب الاستخدام والموارد؛ وباستضافته ذاتيًا على خادم VPS، تنشر المنظومة بأكملها عبر Docker وتديرها من وحدة تحكم ويب أنيقة، دون حد أقصى.
وهو مناسب بشكل خاص لمطوّري Flutter أو React Native أو الويب الذين يريدون خلفية جاهزة للاستخدام مع حزم SDK رسمية، مع الاحتفاظ بالبيانات والمنطق على بنيتهم التحتية الخاصة. تتحكم في الوظائف ومفاتيح API والصلاحيات، وتتوسّع وفق وتيرتك — دون التعرض لحصص الحوسبة السحابية العامة أو زيادات أسعارها.
الفوائد الملموسة لـ Appwrite مُستضاف ذاتيًا
- خلفية شاملة: Auth وDatabases وStorage وFunctions وMessaging في وحدة تحكم واحدة.
- حزم SDK رسمية لـ Flutter وReact Native وWeb وAndroid وiOS وNode وPython والمزيد.
- أكثر من 30 مزوّد OAuth مدمج (Google وGitHub وApple...) دون كتابة أي كود.
- وظائف serverless مُستضافة ذاتيًا: نفّذ منطق أعمالك دون خدمة خارجية.
- صلاحيات دقيقة على مستوى المستند والمجموعة، تُدار من وحدة التحكم.
- لا فوترة لكل تنفيذ ولا حصة للمستخدمين: اشتراك VPS ثابت.
- البيانات مُستضافة على بنيتك التحتية: امتثال مُبسَّط للـ GDPR، ولا تبعية لسحابة طرف ثالث.
- Realtime مدمج: اشترك في تغييرات المستندات والملفات وحالة الجلسة عبر WebSocket.
البنية الداخلية: ما الذي يُشغّله Docker فعلًا
قبل التثبيت، من المفيد معرفة ما ينسّقه Appwrite. يولّد المثبّت الرسمي ملف docker-compose.yml يضم عشرين خدمة على الأقل:
- appwrite — خادم API الرئيسي (PHP، مكشوف على المنفذ 80/443 عبر Traefik).
- appwrite-console — وحدة تحكم الإدارة عبر الويب (React، تُخدَم على نفس النطاق عبر /).
- appwrite-realtime — خدمة WebSocket للاشتراكات في الوقت الفعلي.
- appwrite-worker-* — سلسلة من العمّال للمهام غير المتزامنة: إرسال البريد الإلكتروني، والـ webhooks الصادرة، وتنظيف الملفات المؤقتة، إلخ.
- appwrite-executor — بيئة تشغيل وظائف Functions بلا خادم (Docker-in-Docker).
- mariadb — قاعدة البيانات العلائقية الداخلية (المستخدمون، والمشاريع، وقواعد الصلاحيات).
- redis — الذاكرة المخبئية وقائمة المهام (وظائف workers، والجلسات، وتحديد المعدل).
- traefik — وكيل عكسي مدمج يتولى توجيه HTTPS وشهادات Let's Encrypt.
لخادم VPS تطويري، العقدة الجوهرية core هي الضرورية فقط: API ووحدة التحكم وMariaDB وRedis وTraefik. أما العمّال والـ executor فضروريان في الإنتاج إن كنت تستخدم Functions أو webhooks أو إرسال البريد الإلكتروني. خطّط لـ 4 جيجابايت من RAM على الأقل لهذه المكدس الكاملة.
المتطلبات المادية والبرمجية
لنسخة تطوير أو اختبار، يكفي معالجان افتراضيان (2 vCPU) و4 جيجابايت من RAM مع 40 جيجابايت من SSD. أما للإنتاج مع وظائف serverless نشطة وعدة تطبيقات، فاستهدف 4 vCPU و8 جيجابايت من RAM و80 جيجابايت من SSD — إذ تعمل كل وظيفة في حاويتها المؤقتة الخاصة مما يُحمّل القرص ووحدة المعالجة المركزية.
على الصعيد البرمجي: Ubuntu 22.04 أو 24.04 LTS، وDocker CE وDocker Compose v2 (يدير Appwrite Traefik المدمج الخاص به للتوجيه وSSL)، واسم نطاق يشير إلى IP الخادم — مثل api.myapp.com. يجب أن يكون المنفذان 80 و443 متاحين ومفتوحين في ufw ليحصل Traefik على شهادات Let's Encrypt عبر تحدي ACME.
ملاحظة حول التخزين. تولّد Functions صور Docker وسيطة تتراكم على SSD. دون تنظيف منتظم، قد يمتلئ قرص نسخة تعمل لأشهر عدة. خطّط لمهمة docker system prune --volumes -f أسبوعية عبر cron، وراقب المساحة المتاحة بـ df -h.
نشر Appwrite مُستضاف ذاتيًا باستخدام Docker
تهيئة خادم VPS وفتح المنافذ
ثبّت Docker CE وDocker Compose v2، ثم افتح المنافذ المطلوبة:
ufw allow 80/tcp ufw allow 443/tcp ufw enableوجّه نطاقك (مثل
api.myapp.com) إلى IP الخادم عبر سجل A. انتظر انتشار DNS قبل تشغيل المثبّت — يحتاج Traefik إلى أن يتحلّ النطاق فعلًا لاجتياز تحدي ACME.تشغيل المثبّت التفاعلي الرسمي
نفّذ المثبّت بسطر واحد:
docker run -it --rm \ --volume /var/run/docker.sock:/var/run/docker.sock \ --volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \ --entrypoint="install" \ appwrite/appwriteيسألك المساعد عن النطاق الرئيسي ومنفذ HTTP (80) ومنفذ HTTPS (443) وبريد إلكتروني لـ Let's Encrypt وبعض الخيارات. يولّد ملف
docker-compose.ymlوملف.envبأسرار مولّدة عشوائيًا. لا تعدّل هذه الأسرار يدويًا — غيّرها فقط عبر متغيرات البيئة في.env.التحقق من إعداد النطاق وSSL
بعد بدء التشغيل (
docker compose up -d)، انتظر 30 إلى 60 ثانية حتى يُصدر Traefik الشهادة. تحقق:curl -I https://api.myapp.com/v1/healthيجب أن تكون الاستجابة
HTTP/2 200معcontent-type: application/json. إن لم يحصل Traefik على شهادة بعد، ستحصل على خطأ TLS — وهذا طبيعي خلال الثواني الأولى. في حالة الاستمرار، تحقق من أن المنفذين 80 و443 غير محجوبين بجدار حماية أعلى مستوى وأن النطاق يُحلّ إلى IP الصحيح (dig api.myapp.com).إنشاء حساب المسؤول والمشروع الأول
افتح
https://api.myapp.comفي متصفحك. يدعوك Appwrite إلى إنشاء حساب المسؤول الجذر عند أول وصول — هذا الحساب هو الوحيد الذي يملك صلاحية الوصول إلى إعدادات المنصة. من وحدة التحكم، أنشئ مشروعًا، وأضف منصة (Web أو Flutter أو Apple...) بالإعلان عن hostname المسموح به، واحصل على معرّف المشروع. تُغذّي هذه المعلومات تهيئة SDK من جانب العميل:npm install appwriteimport { Client } from 'appwrite'; const client = new Client() .setEndpoint('https://api.myapp.com/v1') .setProject('<your-project-id>');تعزيز أمان تهيئة الإنتاج
افتح ملف
.envالذي ولّده المثبّت وعدّل المتغيرات التالية:-
_APP_OPTIONS_ABUSE=enabled— يُفعّل تحديد المعدل المدمج لكل IP.
-_APP_OPTIONS_FORCE_HTTPS=enabled— يعيد توجيه جميع طلبات HTTP إلى HTTPS.
-_APP_SMTP_HOST/_APP_SMTP_PORT/_APP_SMTP_SECURE/_APP_SMTP_USERNAME/_APP_SMTP_PASSWORD— هيّئ مرحّل SMTP الخاص بك لإرسال بريد التحقق وإعادة تعيين كلمة المرور.
-_APP_CONSOLE_WHITELIST_ROOT=disabledإذا أردت السماح بالتسجيل المفتوح في وحدة التحكم (غير موصى به في الإنتاج)؛ اتركه علىenabledواملأ_APP_CONSOLE_WHITELIST_EMAILSبالعناوين المخوّلة.أعد تشغيل الخدمات بعد التعديل:
docker compose up -d.إعداد النسخ الاحتياطي التلقائي
وحدتا تخزين Docker التاليتان تحتويان على جميع بيانات Appwrite المستمرة:
-
appwrite-mariadb— قاعدة البيانات (المستخدمون، والمشاريع، والمستندات، والقواعد).
-appwrite-uploads— الملفات التي ترفعها تطبيقات العميل.جدوِل نسخة يومية:
docker exec appwrite-mariadb mysqldump \ -u appwrite -p"$MARIADB_ROOT_PASSWORD" appwrite \ > /backups/appwrite-$(date +%Y%m%d).sqlأرشف أيضًا وحدة التخزين
appwrite-uploads(tar للبيانات أو snapshot للحجم حسب بنيتك التحتية). انسخ أيضًا_APP_OPENSSL_KEY_V1احتياطيًا — يستخدمه Appwrite لتشفير الملفات وبعض البيانات الحساسة. بدون هذا المفتاح، تصبح الملفات المشفرة غير قابلة للاسترداد نهائيًا.
الشبكة وTraefik: ما يحدث خلف الكواليس
Traefik هو نقطة الدخول الشبكية الوحيدة لـ Appwrite: يستمع على المنفذين 80 و443، ويدير شهادات Let's Encrypt، ويوجّه الطلبات إلى الخدمة الداخلية الصحيحة. هذا التكامل شفاف — لا تكتب أي إعداد Traefik، فهو مولَّد من المثبّت.
بعض النقاط المهمة إن أضفت وكيلًا عكسيًا أعلى مستوى (nginx أو Cloudflare Tunnel...):
- لا تضاعف TLS. إذا كان وكيلك الأعلى يُنهي SSL بالفعل ويُحيل بـ HTTP إلى Appwrite، عطّل تحدي ACME بضبط _APP_OPTIONS_FORCE_HTTPS=disabled وتفريغ _APP_SYSTEM_SECURITY_EMAIL_ADDRESS= لمنع Traefik من محاولة الحصول على شهادة لا يمكنه التحقق منها.
- أحل IP الحقيقي. أضف X-Forwarded-For وX-Real-IP في وكيلك الأعلى، وفعّل الثقة بالرؤوس في Traefik (مُعدّ افتراضيًا في مثبّت Appwrite).
- منافذ وحدة التحكم. وحدة التحكم وAPI تُخدَمان تحت نفس النطاق: لا توجّه المنفذ 9501 (Realtime الداخلي) علنًا — يديره Traefik داخليًا.
إذا وضعت Appwrite خلف Cloudflare في الوضع المُوكَّل، اضبط وضع SSL للمنطقة على Full (strict) — في وضع Flexible، يعيد nginx توجيه HTTP←HTTPS مما يخلق حلقة إعادة توجيه لانهائية بين Cloudflare وTraefik.
استكشاف المشكلات الشائعة وإصلاحها
تعرض وحدة التحكم «Could not connect to the Appwrite API».
تحقق من أن المتغيرين _APP_DOMAIN و_APP_DOMAIN_TARGET في .env يتطابقان تمامًا مع النطاق الذي تستخدمه. نطاق فرعي مُهيَّأ بشكل خاطئ (مع www أو بدونها) يمنع Traefik من التوجيه الصحيح. نفّذ docker compose up -d بعد أي تعديل على .env.
رسائل التحقق بالبريد الإلكتروني لا تصل.
لا يوجد في Appwrite مرحّل SMTP مدمج — يجب عليك إعداد _APP_SMTP_* مع خدمة خارجية (Mailgun أو Resend أو خادمك الخاص). دون SMTP مُعدّ، تُقيَّد الرسائل وتُتجاهل. تحقق من سجلات عامل appwrite-worker-mails: docker compose logs appwrite-worker-mails --tail 50.
تنتهي مهلة وظائف Functions serverless.
تبدأ كل وظيفة Function حاويتها Docker الخاصة. على VPS بـ 2 جيجابايت من RAM، يتجاوز التشغيل البارد في أغلب الأحيان 10 ثوانٍ مما يُطلق المهلة الافتراضية. زِد _APP_FUNCTIONS_TIMEOUT في .env وخطّط لـ 4 جيجابايت من RAM على الأقل للاستخدام الإنتاجي. راقب مساحة القرص أيضًا — تبقى صور بيئة التشغيل على SSD بعد التنفيذ.
شهادة SSL لا تتولّد.
يحتاج Traefik إلى استجابة المنفذين 80 و443 من الخارج لاجتياز تحدي ACME. إذا كان جدار حماية أعلى مستوى (قواعد أمان مزوّد VPS) يحجب هذه المنافذ، يفشل التحدي بصمت. اختبر من جهاز خارجي: curl -I http://api.myapp.com يجب أن يستجيب (ولو بـ 302)، لا أن ينتهي بمهلة.
تبدأ MariaDB لكن وحدة التحكم تُظهر أخطاء قاعدة بيانات.
إذا عدّلت .env يدويًا بين إعادتَي تشغيل، تحقق من أن _APP_DB_HOST و_APP_DB_USER و_APP_DB_PASS تتطابق مع القيم في حاوية MariaDB. إعادة تشغيل جزئية (خدمة واحدة فقط) دون docker compose down قد تُبقي حاويات يتيمة مع متغيرات قديمة في الذاكرة.
Appwrite مقابل Supabase: أيهما تستضيف ذاتيًا؟
مرّر الجدول أفقيًا
| المعيار | Appwrite | Supabase |
|---|---|---|
| قاعدة البيانات | MariaDB، نموذج وثائقي | PostgreSQL أصلي، SQL كامل |
| المنهج | موجّه نحو SDK وتطبيقات الجوال | موجّه نحو SQL والتطبيقات العلائقية |
| وظائف serverless | أصلية، متعددة اللغات ومدمجة | Edge Functions (Deno) |
| التثبيت | مُثبّت تفاعلي رسمي | Compose يُهيّأ يدويًا |
| SSL / التوجيه | Traefik مدمج، تلقائي | وكيل عكسي خارجي يجب إضافته |
| البحث الشعاعي / الذكاء الاصطناعي | غير أصلي | أصلي عبر pgvector |
| Realtime | WebSocket مدمج، متعدد الموارد | Postgres CDC عبر Realtime |
| مثالي لـ | Flutter وReact Native، الجوال أولًا | SQL المتقدم، وRAG، والعلائقي |
| وحدة تحكم الإدارة | وحدة تحكم غنية وموجّهة | Studio يتمحور حول جداول SQL |
التحديثات والصيانة المستمرة
لتحديث Appwrite، أعد تشغيل المثبّت بالنسخة الجديدة أو عدّل وسم الصورة في docker-compose.yml ونفّذ docker compose pull && docker compose up -d. يُطبّق Appwrite ترحيلات المخطط تلقائيًا عند بدء تشغيل حاوية API — لا حاجة لأي أمر يدوي.
جدوِل أيضًا تنظيفًا أسبوعيًا للصور Docker اليتيمة لتجنب امتلاء SSD:
docker system prune --volumes -fانسخ _APP_OPENSSL_KEY_V1 احتياطيًا في خزنة منفصلة (مدير أسرار، ملف مشفر خارج الخادم). بدون هذا المفتاح، تجعل استعادة قاعدة البيانات الملفات المشفرة وبعض البيانات الحساسة غير قابلة للقراءة نهائيًا — وهو النقطة الوحيدة غير القابلة للتراجع في أي تثبيت Appwrite.
هذا القالب يوفّر النواة الأساسية — أما Functions فتأتي لاحقًا
يولّد مثبّت Appwrite الرسمي أكثر من 25 حاوية، بما في ذلك عمّال الخلفية وبيئة تنفيذ لدوال Functions ومواقع Sites بلا خادم. للحفاظ على بصمة صغيرة على خادم VPS، لا يوفّر هذا القالب سوى النواة المتّسقة ذاتيًا — خادم API وMariaDB وRedis وTraefik — التي تشغّل بالكامل Auth وDatabases وStorage وRealtime ووحدة التحكّم. أما دوال Functions بلا خادم، والـ webhooks الصادرة، والبريد الإلكتروني في الخلفية فتحتاج إلى حاويتي العامل والمنفّذ الإضافيتين وهي غير مفعّلة هنا. وعندما يحتاجها مشروعك، وسّع إلى حزمة docker-compose الرسمية الكاملة من Appwrite وخطّط لأكثر من 4 GB من ذاكرة RAM. وللنسخ الاحتياطي، خذ لقطات دورية لوحدتَي تخزين Docker وهما appwrite-mariadb (البيانات) وappwrite-uploads (الملفات).