دليل النشر

استضافة Penpot على VPS: بديل Figma مفتوح المصدر

انشر على VPS Cloud ←

دليل عملي

التطوير

استضافة Penpot على VPS: بديل Figma مفتوح المصدر

أصبح Figma معيار تصميم الواجهات، لكنه يبقى خدمة مملوكة: ملفاتكم عند طرف ثالث وتُفوتر لكل مقعد. Penpot (برخصة MPL-2.0) هو البديل المفتوح المصدر: أداة تصميم تعاونية في الزمن الفعلي، مبنية على معايير الويب (SVG وCSS)، تستضيفونها بأنفسكم عبر Docker. يمضي هذا الدليل من التثبيت على VPS من ServOrbit إلى التشغيل اليومي: المتطلبات المحددة بالأرقام، والبريد الإلكتروني، والنسخ الاحتياطي، والتحديث، وحد الذاكرة، والاستيراد من Figma، وحل المشكلات برسائل الخطأ الحقيقية.

12 دقيقةً للقراءةعدد الخطوات: 8
المحتويات· Penpot مقابل Figma: ما الذي يغيّره البديل المفتوح المصدر فعلاً1/14
  1. 01Penpot مقابل Figma: ما الذي يغيّره البديل المفتوح المصدر فعلاً
  2. 02ما يقدمه Penpot مباشرةً
  3. 03البنية: حزمة Docker واحدة ونقطة دخول HTTP وحيدة
  4. 04خدمات حزمة Penpot
  5. 05المتطلبات بالأرقام: الذاكرة والمعالج والقرص والمنافذ
  6. 06النشر في 8 خطوات
  7. 07الإعداد بعد التثبيت: البريد الإلكتروني وتخزين الملفات
  8. 08النسخ الاحتياطي والتحديث
  9. 09الذاكرة: ما يرد في البلاغ #3299 وكيف نضع لها حداً
  10. 10تحديد الذاكرة: حد ومراقبة وإعادة تشغيل مجدولة
  11. 11استيراد ملفاتكم من Figma
  12. 12دمج Penpot في سير عمل Git
  13. 13Penpot MCP: قودوا تصاميمكم من مساعد ذكاء اصطناعي
  14. 14حل المشكلات: الأخطاء المبلَّغ عنها فعلاً

Penpot مقابل Figma: ما الذي يغيّره البديل المفتوح المصدر فعلاً

يتشارك Figma وPenpot النموذج نفسه: تصميم متجهي داخل المتصفح، وتعاون في الزمن الفعلي، ومكوّنات قابلة لإعادة الاستخدام، وتسليم مدمج للمطورين. يكمن الفرق الجوهري في نموذج البيانات وفي التحكم. يخزّن Figma كل شيء على خوادمه بصيغة مملوكة. أما Penpot فيعتمد على SVG وCSS لغةً أساسية ويعمل على بنيتكم التحتية: أنتم تقررون أين تعيش الملفات، ومن يتصل، ومتى تُحدّثون. بالنسبة إلى فريق يستضيف شيفرته على Gitea ووثائقه على Docmost ومراسلاته على Mattermost، فإن استضافة أداة التصميم على ServOrbit أيضاً هي الخطوة المنطقية التالية. الثمن هو التشغيل: النسخ الاحتياطي والتحديثات وتحديد الحجم تصبح من مسؤوليتكم، وهذا ما تعالجه الأقسام التالية.

ما يقدمه Penpot مباشرةً

  • تصميم متجهي في الزمن الفعلي — عدة مصممين على الملف نفسه في آن واحد، مؤشرات مرئية، وتعليقات سياقية على الطبقات.
  • مكوّنات ومكتبات مشتركة — أنشئوا أنظمة تصميم وانشروها في مكتبات مشتركة بين المشاريع.
  • تسليم أصلي للمطورين — مفتش CSS، وتصدير الأصول، وملاحظات وقياسات مسافات مولّدة من التصاميم.
  • نماذج أولية تفاعلية — اربطوا اللوحات (boards) بانتقالات وحاكوا التنقل دون مغادرة الأداة.
  • تخطيطات مرنة — auto layouts وشبكات CSS وقيود إعادة التحجيم قريبة مما يوفره Figma.
  • صيغ مفتوحة — تصدير .penpot (أرشيف كامل) وتصدير SVG لكل لوحة، يُقرأ في Inkscape أو في أي محرر متجهي.
  • خادم MCP — تتيح خدمة penpot-mcp ملفاتكم للمساعدين المتوافقين مع MCP (انظروا الإطار المخصص أدناه).

البنية: حزمة Docker واحدة ونقطة دخول HTTP وحيدة

Penpot حزمة من عدة حاويات. يعلن ملف Compose الذي ينشره المشروع، في الإصدار 2.18، ثماني خدمات: penpot-frontend وpenpot-backend وpenpot-admin-console وpenpot-mcp وpenpot-exporter وpenpot-postgres وpenpot-valkey وpenpot-mailpit. يشغّل قالب ServOrbit مجموعة جزئية بحسب إصداره: يُقرأ العدد الدقيق بالأمر docker compose ps على الـ VPS. يعطي الجدول أدناه دور كل خدمة كما يصفه ملف Compose الأصلي. منفذ واحد فقط يهم من جهة التعريض: تستمع الواجهة الأمامية داخلياً على 8080 وينشرها Compose على 9001. ضعوا الوكيل العكسي أمام هذا المنفذ ولا شيء غيره.

خدمات حزمة Penpot

مرّر الجدول أفقيًا

الخدمةالدورما يجب معرفته
`penpot-frontend`يقدّم التطبيق ويوجّه الطلبات إلى بقية الخدماتالخدمة الوحيدة التي تُعرَّض: المنفذ 9001 في Compose الأصلي
`penpot-backend`واجهة API والمنطق الوظيفي (تطبيق Java/Clojure)الملفات (assets) في وحدة تخزين؛ يُضبط SMTP والتخزين هنا
`penpot-exporter`تصدير PNG وPDF وSVG عبر متصفح بلا واجهةيصل إلى التطبيق عبر `PENPOT_PUBLIC_URI`: شهادة صالحة مطلوبة
`penpot-postgres`قاعدة PostgreSQL 15: الحسابات والمشاريع والملفاتوحدة التخزين `penpot_postgres_v15` يجب نسخها احتياطياً
`penpot-valkey`إشعارات الزمن الفعلي (websockets) وذاكرة مؤقتةمحدودة بـ 128 ميغابايت (`--maxmemory 128mb`) في Compose الأصلي
`penpot-mcp`خادم MCP لمساعدي الذكاء الاصطناعييُفعَّل بالعلم `enable-mcp`، وwebsocket على `/mcp/ws`
`penpot-admin-console`وحدة التحكم الإداريةأُضيفت إلى الحزمة في 2.18، العلم `enable-admin-console`
`penpot-mailpit`صندوق SMTP للاختبار (واجهته على المنفذ 8025)يُستبدل بخادم SMTP حقيقي في الإنتاج

المتطلبات بالأرقام: الذاكرة والمعالج والقرص والمنافذ

لا تنشر الوثائق الأصلية حداً أدنى لفريق صغير. فهي تذكر أن 4 معالجات و16 غيغابايت من الذاكرة تكفي لخدمة آلاف المستخدمين، وتتيح لكم التحفظ عند تخصيص الموارد. وبالنسبة إلى القرص توصي بالبدء بمساحة قاعدة بيانات بين 50 و100 غيغابايت قابلة للتوسع، وهي تغطي حتى 10 محررين، ثم نحو 5 غيغابايت إضافية لكل محرر زائد. الحجم الفعلي يتبع الاستخدام وتعقيد الملفات لا عدد الحسابات. توصيتنا التحريرية لفريق من بضعة أشخاص: VPS بذاكرة 4 غيغابايت مع حد لكل خدمة (قسم الذاكرة أدناه)، وهو يترك هامشاً لتصدير الملفات الثقيلة؛ ويكفي 2 غيغابايت للتجربة. على مستوى الشبكة افتحوا 80 و443 نحو الوكيل العكسي، ولا تفتحوا 9001 أو 8025 مباشرةً. الحد الأقصى لجسم الطلب في Compose هو 367001600 بايت (350 ميبيبايت): يجب أن يوافقه client_max_body_size في وكيلكم. أما على جهاز المستخدم فتوصي الوثائق بآخر إصدار مستقر من Chrome.

النشر في 8 خطوات

  1. اطلبوا VPS من ServOrbit

    خصصوا 4 غيغابايت من الذاكرة للاستخدام الجماعي و2 غيغابايت للتجربة. Ubuntu 24.04 LTS هو القالب الافتراضي. أبقوا 50 غيغابايت على الأقل من القرص حرة إن كنتم تستوردون ملفات كبيرة.

  2. وجّهوا نطاقاً فرعياً إلى الـ VPS

    أنشئوا سجل A للنطاق design.your-domain.com يشير إلى عنوان IP الخاص بالـ VPS. يصدر مزوِّد ServOrbit شهادة Let's Encrypt. نطاق بـ HTTPS ضروري: يضع Penpot ملفات تعريف ارتباط الجلسة بالسمة secure افتراضياً، وتحصر الوثائق الأصلية العلم disable-secure-session-cookies بالتجارب خارج الإنتاج.

  3. ثبّتوا من السوق

    في لوحة ServOrbit: السوق، التعاون، Penpot، نشر. تشغّل مهمة AWX الحاويات وتولّد PENPOT_SECRET_KEY وتضبط PENPOT_PUBLIC_URI على نطاقكم. تستجيب الواجهة على https://design.your-domain.com خلال دقائق.

  4. تحققوا من تشغيل كل الخدمات

    اتصلوا عبر SSH ونفّذوا docker compose ls لتحديد ملف Compose، ثم docker compose -p penpot -f docker-compose.yaml ps. يجب أن تكون كل خدمة في حالة running، وأن تكون penpot-postgres وpenpot-valkey في حالة healthy. تُقرأ السجلات بالأمر docker compose -p penpot -f docker-compose.yaml logs -f.

  5. أنشئوا حسابكم

    التسجيل مفتوح افتراضياً. افتحوا https://design.your-domain.com وانقروا « إنشاء حساب »: في Compose الأصلي التحقق بالبريد الإلكتروني معطّل (disable-email-verification)، فيصبح الحساب فعالاً فوراً. أنشئوا حسابكم حالاً قبل أن يفعل ذلك غيركم.

  6. أغلقوا التسجيل العام

    أضيفوا العلم disable-registration إلى PENPOT_FLAGS (الواجهة الأمامية والخلفية) ثم أعيدوا إنشاء الحاويات. تستمر الدعوات في العمل ما دام enable-login-with-password مفعّلاً. لإنشاء حساب دون دعوة نفّذوا docker exec -ti penpot-penpot-backend-1 python3 manage.py create-profile: يتطلب السكربت العلم enable-prepl-server، وقد يختلف اسم الحاوية، فتحققوا منه بالأمر docker ps.

  7. اربطوا خادم SMTP حقيقياً

    بدون SMTP لا تُرسل أي دعوة ولا رسالة لإعادة تعيين كلمة المرور. انظروا القسم التالي لمعرفة المتغيرات.

  8. استوردوا ملفات Figma

    لا يفتح Penpot ملفات .fig مباشرةً. المسار الرسمي يمر عبر إضافة Figma المسماة « Penpot Exporter »، وهي تنتج أرشيف .zip يُستورد في Penpot. يرد الإجراء وحدوده مفصلاً أدناه.

الإعداد بعد التثبيت: البريد الإلكتروني وتخزين الملفات

بالنسبة إلى البريد فعّلوا enable-smtp في PENPOT_FLAGS واضبطوا في الخلفية PENPOT_SMTP_DEFAULT_FROM وPENPOT_SMTP_DEFAULT_REPLY_TO وPENPOT_SMTP_HOST وPENPOT_SMTP_PORT (القيمة 587 في المثال الأصلي) وPENPOT_SMTP_USERNAME وPENPOT_SMTP_PASSWORD وPENPOT_SMTP_TLS. يشير Compose الأصلي افتراضياً إلى penpot-mailpit الذي يحتفظ بالرسائل في الذاكرة ويفقدها عند إعادة إنشاء الحاوية. في الإنتاج أزيلوا أيضاً disable-email-verification الذي لا تنصح به الوثائق خارج التجارب. أما بالنسبة إلى الملفات فتُخزَّن الصور ومقاطع SVG التي يرفعها المستخدمون افتراضياً على نظام الملفات، في وحدة التخزين penpot_assets المركّبة على /opt/data/assets (PENPOT_OBJECTS_STORAGE_BACKEND: fs). والتخزين المتوافق مع S3 ممكن عبر PENPOT_OBJECTS_STORAGE_BACKEND: s3 مع bucket ونقطة نهاية اختيارية والمتغيرين AWS_ACCESS_KEY_ID وAWS_SECRET_ACCESS_KEY. منذ الإصدار 2.11.0 استُبدلت الأسماء القديمة PENPOT_STORAGE_ASSETS_* بالأسماء PENPOT_OBJECTS_STORAGE_*: إن أعدتم استخدام ملف Compose قديم فغيّروا أسماءها.

النسخ الاحتياطي والتحديث

لنسخة Penpot حالتان يجب نسخهما معاً: قاعدة PostgreSQL ووحدة تخزين الملفات. تحذّر الوثائق الأصلية من أنه لا يمكن نسخ مجلد بيانات وحدة تخزين Docker مباشرةً، وتحيل إلى إجراء النسخ الاحتياطي لوحدات التخزين في Docker. نهجنا: تصدير منطقي للقاعدة بالأمر docker exec penpot-penpot-postgres-1 pg_dump -U penpot penpot > penpot.sql، ثم أرشفة وحدة تخزين الملفات عبر حاوية مؤقتة تركّبها للقراءة فقط. اعثروا على أسماء الوحدات بالأمر docker volume ls. خذوا النسختين في اللحظة نفسها، وإلا قد تشير القاعدة إلى ملفات غائبة عن الأرشيف، وجرّبوا الاستعادة على VPS آخر قبل أن تحتاجوا إليها. وللتحديث ثبّتوا الإصدار عبر PENPOT_VERSION بدل اتباع آخر صورة، ونفّذوا docker compose -p penpot -f docker-compose.yaml pull ثم up -d، وتقدموا بخطوات صغيرة: تنصح الوثائق بعدم القفز بين إصدارات متباعدة. في 1 نوفمبر 2026 كان آخر إصدار منشور هو 2.18.5. وإن كنتم تصونون ملف Compose خاصاً بكم، فقد أضاف الإصدار 2.18 خدمة penpot-admin-console والمتغير PENPOT_ADMIN_CONSOLE_URI في الواجهة الأمامية والخلفية. انسخوا احتياطياً دائماً قبل التحديث.

الذاكرة: ما يرد في البلاغ #3299 وكيف نضع لها حداً

البلاغ #3299 في مشروع penpot، المفتوح في يونيو 2023، ما زال مفتوحاً وتلقى رسالة في أكتوبر 2026. يجمع شهادات عن استهلاك مرتفع للذاكرة في تثبيتات Docker: مستخدم يذكر نحو 20 غيغابايت مشغولة بعد ثلاثة إلى أربعة أيام على خادم بذاكرة 64 غيغابايت، وآخر أكثر من 50 غيغابايت تطلبها آلة افتراضية بلا مستخدمين، وثالث 15 غيغابايت لمستخدم واحد مع إعادة تشغيل الخلفية كل 12 ساعة. هذه تقارير فردية لم يُعد إنتاجها: يرد عضو في فريق Penpot داخل النقاش بأن لديهم تثبيتات Docker بحركة كبيرة دون هذا العرض، ويطلب ملفاً وسجلات للتشخيص. لذلك لا يمكننا الوعد برقم استهلاك. ما يمكننا قوله هو كيف لا نترك خدمة واحدة تقرر وحدها: الخلفية عملية Java، ومن دون حد على الحاوية تحدد آلة Java الافتراضية حجم الـ heap بحسب الذاكرة التي تراها، أي ذاكرة المضيف كله. حد لكل خدمة يحوّل انحرافاً صامتاً إلى إعادة تشغيل مضبوطة.

تحديد الذاكرة: حد ومراقبة وإعادة تشغيل مجدولة

يذكر أحد المساهمين في النقاش #3299 أنه أضاف mem_limit: 12g إلى كل خدمات Compose ليبقى الاستهلاك محتملاً. على VPS بذاكرة 4 غيغابايت ضعوا قيماً أقل، مثلاً mem_limit: 2g على penpot-backend وmem_limit: 1g على penpot-exporter، واتركوا الباقي لـ PostgreSQL والنظام. يضيف سكربت تشغيل الخلفية JVM_OPTS وJAVA_OPTS إلى سطر أوامر Java: يمكنكم تمرير -XX:MaxRAMPercentage=70 هناك، وهو خيار قياسي في JVM، لكن وثائق Penpot لا تصف أي ضبط لـ JVM، فجرّبوه قبل الإنتاج. راقبوا بالأمر docker stats --no-stream، وإن انحرفت الخلفية رغم الحد فجدولوا إعادة تشغيل ليلية (docker compose -p penpot -f docker-compose.yaml restart penpot-backend): يعيد المتعاونون وصل websockets. Valkey محدود أصلاً بـ 128 ميغابايت في Compose الأصلي. وإن بلغتم الحد كثيراً فهذه إشارة لاختيار عرض VPS بذاكرة أكبر، لا لرفع الحد عشوائياً.

استيراد ملفاتكم من Figma

خلافاً لما يُقرأ أحياناً، لا يستورد Penpot ملف .fig. يصون المشروع إضافة لـ Figma اسمها « Penpot Exporter » تحوّل ملف Figma إلى أرشيف .zip قابل للاستيراد. في Figma افتحوا الملف، ثم Resources ثم Plugins، وابحثوا عن « Penpot Exporter » وشغّلوا التصدير. في Penpot افتحوا قائمة النقاط الثلاث لمشروع أو للمسودات، واختاروا « Import Penpot files » وحددوا ملف .zip. بحسب README الخاص بالإضافة يُنقل ما يلي: الأشكال الأساسية والمتجهات والإطارات والأقسام (لوحات boards في Penpot) والمجموعات والأقنعة والنصوص والتعبئة والحدود والظلال والمكوّنات ونسخها وauto layouts والنسخ المتغيرة ومكتبات الألوان والخطوط. ولا تُنقل إعدادات النماذج الأولية. تبقى الملفات الضخمة نقطة صعبة لأن التصدير يمر على كل عقدة تحت حدود واجهة Figma البرمجية، وقد تختلف بعض عمليات العرض قليلاً. استوردوا ملف اختبار أولاً، وقارنوا المكوّنات والخطوط، ثم انقلوا الباقي. تُرفع الخطوط المخصصة إلى Penpot.

دمج Penpot في سير عمل Git

لا يخزّن Penpot تصاميمكم كملفات نصية في مستودع: مصدر الحقيقة هو قاعدة PostgreSQL. غير أن تصديرين يناسبان Git. أرشيف .penpot نسخة احتياطية محمولة لملف. وتصدير SVG للوحة ينتج نصاً مقروءاً يمكنكم رفعه إلى Gitea، مثلاً لأيقونات ورسوم نظام التصميم. يعرض طلب الدمج حينئذ الفرق في SVG، ويمكن لخط CI أن يكشف تغييراً غير متوقع. يبقى هذا النهج اتفاقاً داخل الفريق: يفترض إعادة التصدير بعد كل تغيير، وهو ما يمكن لسكربت أو لمراجعة تصميم أن يذكّركم به.

Penpot MCP: قودوا تصاميمكم من مساعد ذكاء اصطناعي

يتضمن Compose الأصلي خدمة penpot-mcp تُفعَّل بالعلم enable-mcp، ويجب أن يمرر وكيلها العكسي websocket على /mcp/ws إضافةً إلى /ws/notifications. يستطيع حينئذ عميل متوافق مع MCP أن يتصل بنسختكم. اقصروا هذا الوصول على حسابات موثوقة وقدّموه عبر HTTPS. جرّبوا أولاً على ملف مسودة، ثم عمّموا إن أقنعتكم النتيجة.

حل المشكلات: الأخطاء المبلَّغ عنها فعلاً

  • شريط « Something wrong has happened » أو رفض ملف تعريف الارتباط auth-token — أُبلغ عنه على خادم يُوصَل إليه عبر HTTP من الشبكة المحلية. جواب عضو في فريق Penpot: ملفات تعريف الارتباط بالسمة secure افتراضياً، فيجب تقديم الواجهة الأمامية والخلفية عبر HTTPS. قدّموا النسخة خلف شهادة صالحة واضبطوا PENPOT_PUBLIC_URI على العنوان الدقيق.
  • خطأ داخلي بعد بضع نقرات على التسجيل أو الدخول — أُبلغ عنه مع disable-secure-session-cookies على وصول HTTP عام. العلاج نفسه: HTTPS. هذا العلم ليس حلاً للإنتاج.
  • WebSocket connection to 'wss://…/ws/notifications…' failed: Invalid frame header — أُبلغ عنه فور تسجيل الدخول مع تجمّد الواجهة خلف Nginx. الجواب المقدَّم في المجتمع هو تمرير /ws/notifications مع الترويستين Upgrade وConnection إلى المنفذ 9001. ولا يؤكد النقاش أن ذلك حلّ حالة صاحب السؤال.
  • net::ERR_CERT_AUTHORITY_INVALID في سجلات penpot-exporter — يفشل التصدير. يحمّل المصدِّر التطبيق عبر PENPOT_PUBLIC_URI: ومع شهادة موقّعة ذاتياً أو غير معروفة لا يستطيع التحقق من الاتصال. استخدموا شهادة صادرة عن جهة معروفة.
  • تصدير PDF ينتهي مهلته دون رسالة واضحة — أُبلغ عنه في تثبيت يدوي كان المصدِّر يتلقى فيه PENPOT_PUBLIC_URI=http://localhost. يجب أن يصل المصدِّر إلى العنوان العام للتطبيق لا إلى عنوان محلي لحاويته هو.
  • تعذّر تسجيل الدخول ولا خيط واضح — تحققوا أولاً من docker compose -p penpot -f docker-compose.yaml ps، ثم من سجلات الخدمة المعنية، ومن وحدة تحكم المتصفح (F12) التي تعرض إصدار Penpot الدقيق والطلبات الفاشلة.

استوديو تصميمك تحت سيطرتك

انشر Penpot على خادم ServOrbit وامنح فريقك مساحة تصميم تعاونية ذات سيادة — دون اشتراك لكل مستخدم أو بيانات تصميم لدى Adobe.