لماذا تستضيف Excalidraw بنفسك بدلاً من النسخة العامة
تعمل النسخة العامة على excalidraw.com بشكل جيد للرسم السريع الفردي. إلا أنها تُمرّر جلسات التعاون في الوقت الفعلي عبر خادم تديره شركة Excalidraw s.r.o. قد يكون ذلك مقبولاً لجلسة عصف ذهني عابرة، لكنه أقل قبولاً حين تحتوي اللوحات على نماذج تدفق العملاء أو مخططات البنية الداخلية أو واجهات مشاريع مشمولة بالسرية.
استضافة Excalidraw ذاتياً تنقل حدود التحكم إلى بنيتك التحتية الخاصة. تمر الجلسات عبر خادمك WebSocket على نطاقك الخاص دون المرور بطرف ثالث. أنت من يقرر من يتصل — عبر قائمة IP المسموح بها أو SSO OIDC أو HTTP Basic Auth أمام nginx. وبما أن المكوّنَين منشوران بموجب رخصة MIT، لا توجد قيود تجارية بصرف النظر عن عدد العملاء أو المتعاونين.
الفوائد الملموسة
- لا رسوم برمجية — المكوّنان (الواجهة وخادم التعاون) برخصة MIT. تدفع مقابل VPS فقط.
- سرية النماذج — تبقى جلسات الرسم على بنيتك التحتية ولا يمر أي ملف تصميم عبر طرف ثالث.
- التحكم في الوصول — قائمة IP أو SSO OIDC أو HTTP Basic Auth أمام nginx حسب مستوى العزل المطلوب.
- جلسات وأعضاء غير محدودين — لا سقف يفرضه الخطة؛ الحد الوحيد هو ذاكرة RAM للخادم، وخادم
excalidraw-roomخفيف الوزن. - استمرارية اختيارية — ربط وحدة تخزين Docker أو حاوية S3 متوافقة لأرشفة اللوحات المصدَّرة بصيغة JSON.
- التكامل مع مجموعة الأدوات المستضافة ذاتياً — Excalidraw إلى جانب Penpot وMattermost وDocmost يُغلق محيط SaaS لوكالة بأكملها.
البنية: حاويتان بأدوار مختلفة
يفصل Excalidraw ما يعتبره معظم الناس أداةً واحدةً إلى مكوّنَين مستقلَّين:
- excalidraw/excalidraw — الواجهة المُجمَّعة بـ React، تُقدَّم كموقع ثابت عبر nginx داخل الحاوية. لا تشغّل خادماً تطبيقياً. قيدها الوحيد هو المتغير VITE_APP_WS_SERVER_URL الذي يجب أن يشير إلى خادم الغرفة وقت البناء. هذا المتغير مدمج في حزمة JavaScript: تغييره على حاوية قيد التشغيل لا يُحدث أي أثر.
- excalidraw/excalidraw-room — خادم Node.js/Socket.IO يُعيد توجيه أحداث الرسم في الذاكرة بين المشاركين في الجلسة ذاتها. إنه عديم الحالة: لا يُخزّن شيئاً وينسى كل شيء عند إعادة التشغيل. الرسومات تعيش في localStorage المتصفح أو تُصدَّر يدوياً.
النتيجة العملية: الصورة الرسمية لـ Docker تُضمّن عنوان خادم التعاون الخاص بـ Excalidraw. لإعادة التوجيه نحو excalidraw-room الخاص بك، تحتاج إلى بناء صورتك الخاصة مع تعيين VITE_APP_WS_SERVER_URL على نطاقك.
المتطلبات الأساسية
يغطي VPS Start من ServOrbit (2 نواة، 4 GB RAM) الحالة العادية: الواجهة الثابتة شبه خالية من الحمل، ويستهلك excalidraw-room أقل من 256 ميغابايت في الظروف العادية. مع عشرة متعاونين متزامنين ستبقى بعيداً عن نصف الذاكرة المتاحة.
ما تحتاجه قبل البدء:
قائمة التحقق من المتطلبات
- خادم VPS بما لا يقل عن 1 نواة و512 ميغابايت RAM (يُوصى بـ 1 غيغابايت للفريق).
- Docker Engine وإضافة Docker Compose مثبَّتان (للتحقق:
docker compose version). - اسم نطاق مُوجَّه نحو IP الخادم — بدون TLS تُحجب WebSockets في المتصفحات الحديثة.
- وصول SSH بصلاحيات root أو مستخدم بصلاحيات
sudo. - شهادة TLS صالحة — يهيئ ServOrbit Let's Encrypt تلقائياً.
نشر Excalidraw في 5 خطوات
إنشاء VPS وتثبيت Docker
شغّل VPS Ubuntu 24.04 من لوحة تحكم ServOrbit. بعد الاتصال عبر SSH، إن لم يكن Docker مثبتاً بعد، شغّل:
curl -fsSL https://get.docker.com | shتحقق من استجابة Docker Compose Plugin قبل المتابعة:
docker compose versionبناء الصورة مع رابط التعاون الخاص بك
انسخ المستودع الرسمي ثم ابنِ الصورة مع استبدال نطاقك. استبدل
collab.yourdomain.comبالنطاق الفرعي الذي تخصصه لـexcalidraw-room:git clone https://github.com/excalidraw/excalidraw.git cd excalidraw docker build \ --build-arg VITE_APP_WS_SERVER_URL=wss://collab.yourdomain.com \ -t my-excalidraw:latest .تُدمج هذه الخطوة عنوان خادم WebSocket في حزمة JavaScript. إن غيّرت النطاق لاحقاً ستحتاج إلى إعادة البناء.
كتابة ملف docker-compose.yml
أنشئ مجلد عمل وضع الملف التالي. تستمع الخدمتان داخلياً؛ nginx (الخطوة التالية) هو نقطة الدخول العامة الوحيدة:
mkdir ~/excalidraw-stack && cd ~/excalidraw-stackمحتوى
docker-compose.yml:services: excalidraw: image: my-excalidraw:latest restart: unless-stopped networks: - excalidraw excalidraw-room: image: excalidraw/excalidraw-room:latest restart: unless-stopped networks: - excalidraw networks: excalidraw:شغّل المجموعة:
docker compose up -dإعداد nginx مع ترويسات WebSocket
هذه الخطوة هي المكان الذي تفشل فيه معظم عمليات النشر بصمت: بدون ترويستَي
UpgradeوConnection، يفتح المتصفح اتصالاً HTTP عادياً بدلاً من WebSocket، وتبدو ميزة التعاون كأنها لا تعمل دون أي رسالة خطأ.كتلة nginx للواجهة الأمامية لـ Excalidraw (
draw.yourdomain.com):server { listen 443 ssl; server_name draw.yourdomain.com; location / { proxy_pass http://excalidraw:80; proxy_set_header Host $host; } }كتلة nginx لخادم الغرفة (
collab.yourdomain.com):server { listen 443 ssl; server_name collab.yourdomain.com; location / { proxy_pass http://excalidraw-room:80; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_read_timeout 86400s; } }أعِد تحميل nginx (
nginx -s reload) بعد وضع الكتل.اختبار التعاون في الوقت الفعلي
افتح
https://draw.yourdomain.comفي علامتَي تبويب أو متصفحَين مختلفَين. انقر على Live collaboration في شريط الأدوات وأنشئ جلسة. انسخ رابط الجلسة في علامة التبويب الثانية.ارسم شيئاً في علامة التبويب الأولى: يجب أن تظهر اللمسة في الثانية فوراً. إن لم تظهر، تحقق أولاً من ترويسات WebSocket في nginx (تُظهر أدوات الشبكة في المتصفح إن كان الاتصال قد ارتقى إلى
101 Switching Protocols).
استمرارية اللوحات: نهجان
بشكل افتراضي، يكون excalidraw-room عديم الحالة تماماً. إن أُعيد تشغيل الخادم، تُفقد الجلسة الجارية — لكن كل مشارك يحتفظ محلياً بما رسمه في localStorage.
الخيار الأول — تصدير JSON تلقائي. اضبط مهمة cron أو سكريبتاً يستدعي واجهة تصدير Excalidraw ويحفظ ملفات .excalidraw في وحدة تخزين Docker. يمكن إعادة استيراد هذه الملفات في أي وقت من الواجهة.
الخيار الثاني — حاوية S3 متوافقة. يوفر ServOrbit تخزين كائنات متوافق مع S3. اربط حاوية التخزين كوجهة لأرشفة التصديرات؛ الاستعادة بعد عطل تتم بإعادة استيراد آخر ملف محفوظ.
Excalidraw المستضاف ذاتياً مقابل بدائل SaaS
مرّر الجدول أفقيًا
| المعيار | Excalidraw (ذاتي) | Miro | FigJam |
|---|---|---|---|
| التكلفة لكل مستخدم | لا شيء (VPS فقط) | مدفوع بالمقعد | مدفوع بالمقعد |
| استضافة البيانات | بنيتك التحتية | Miro Inc. | Adobe / Figma |
| الأعضاء المتزامنون | غير محدود (RAM فقط) | محدود بالخطة | محدود بالخطة |
| رخصة البرنامج | MIT (مفتوح المصدر) | خاصة | خاصة |
| قابل للاستضافة الذاتية | نعم، حاويتان | لا | لا |
| التحكم في الوصول | IP / SSO / Basic Auth | SSO (خطط Pro) | SSO (خطط Edu+) |
للمزيد: SSO وقوائم IP المسموح بها
بالنسبة للوكالات ذات متطلبات سرية صارمة، قد لا يكون نشر Excalidraw على نطاق فرعي عام مقبولاً دائماً. ثمة إعدادان شائعان يُحكمان الوصول دون تعديل Excalidraw نفسه.
HTTP Basic Auth عبر nginx. أضف توجيه auth_basic أمام كتلة location / للواجهة الأمامية. يجب على أي شخص يحاول فتح الواجهة المصادقة قبل تحميل تطبيق React. سهل التطبيق وكافٍ للمشاريع الداخلية.
قائمة IP المسموح بها. إن اتصل المتعاونون من عناوين IP ثابتة أو شبكة VPN مؤسسية، تكفي كتلة allow/deny في nginx لإغلاق الوصول:
allow 203.0.113.0/24;
allow 198.51.100.42;
deny all;SSO OIDC عبر وكيل عكسي للمصادقة. للفرق التي تمتلك بالفعل مزود هوية (Keycloak أو Authelia أو Authentik)، يُفوَّض التحقق من الهوية إلى SSO الحالي عبر وكيل كـ Oauth2-Proxy أو Authelia أمام nginx. لا يحتاج Excalidraw إلى معرفة وجود طبقة المصادقة الإضافية.
التكامل مع مجموعة الأدوات المستضافة ذاتياً
يتكامل Excalidraw بشكل طبيعي مع مجموعة الأدوات المستضافة ذاتياً. إن نشرت Mattermost للتواصل الجماعي، يمكنك لصق رابط جلسة Excalidraw في قناة ودعوة المتعاونين للانضمام إلى اللوحة مباشرةً. وإن كان Penpot يغطي التصميم عالي الدقة، يتولى Excalidraw العمل الأولي — الواجهات السريعة ومخططات التدفق وجلسات العصف الذهني — قبل انتقال التصاميم إلى Penpot.
هذا التكامل هو الحجة الحقيقية في مواجهة SaaS: تبقى كل أداة في نطاق كفاءتها دون اشتراك منصة يفوتر عن ميزات لا تحتاجها.