لماذا تستضيف ERPNext ذاتيًا على VPS
يجمع نظام ERP أكثر بيانات الشركة حساسية: القيود المحاسبية، والهوامش، وبطاقات العملاء والموردين، والرواتب. غالبًا ما تُفوتِر عروض SaaS لكل مستخدم شهريًا، وهو ما يصبح مكلفًا مع نمو الفرق. على VPS مخصّص، تدفع ثمن الخادم مرة واحدة، وتضيف من المستخدمين ما تحتاج، وتبقى قاعدة البيانات تحت سيطرتك مع نسخ احتياطي وفق قواعدك الخاصة.
يقوم ERPNext على Frappe، وهو إطار عمل Python/JavaScript يجعل الكود المصدري قابلًا للقراءة والتوسعة. تمنحك الاستضافة الذاتية التحكم في جدول التحديثات واختيار التطبيقات المكملة (HRMS، e-Commerce، Education، Healthcare) وإمكانية كتابة وحداتك الخاصة دون الاعتماد على مورّد.
الفوائد الملموسة لـ ERPNext مُستضاف ذاتيًا
- دون أي تكلفة لكل مستخدم: أضف فرقك دون زيادة الفاتورة.
- سيادة على البيانات المحاسبية وبيانات الموارد البشرية، التي تبقى على خادمك.
- جميع الوحدات متاحة (محاسبة، مخزون، CRM، تصنيع، رواتب) دون مستوى مدفوع.
- تخصيص حر عبر إطار عمل Frappe والتطبيقات التكميلية.
- نسخ احتياطي واحتفاظ مُداران، ملائمان لالتزاماتك القانونية.
- قابلية التوسّع: ارفع RAM/vCPU مع نمو حجم المعاملات.
الوحدات الرئيسية في ERPNext
يغطي ERPNext الدورة التشغيلية الكاملة للمؤسسة. المحاسبة: دليل حسابات متعدد العملات، دفتر الأستاذ العام، التقارير النظامية (الميزانية، حساب النتائج)، إدارة ضريبة القيمة المضافة والتسوية البنكية. المبيعات والمشتريات: عروض الأسعار والطلبات والتسليمات والفواتير وإشعارات الدائن مع مسارات الموافقة. إدارة المخزون: مستودعات متعددة، دُفعات وأرقام تسلسلية، جرد دوري، تقييم FIFO أو متوسط متحرك. CRM: العملاء المحتملون والفرص والحملات وخط أنابيب المبيعات مع لوحة نشاط. التصنيع: قوائم المواد (BOM)، أوامر العمل، تتبع محطات العمل والهالك. الموارد البشرية: ملفات الموظفين، الإجازات، الحضور، كشوف الرواتب قابلة التهيئة حسب البلد وتقييم الأداء.
تُفعَّل كل وحدة من مكتب ERPNext؛ تثبّت ما تحتاجه فحسب، وتُعرَّف صلاحيات الوصول بالأدوار على مستوى المستند.
المتطلبات العتادية والبرمجية
ERPNext أكثر تطلّبًا من المتوسط. احسب على الأقل 2 vCPU و4 GB من الذاكرة RAM للاستخدام الاختباري، و4 vCPU / 8 GB من الذاكرة RAM للإنتاج مع عدة مستخدمين متزامنين. خصّص 20 GB من القرص لقاعدة بيانات MariaDB وRedis والملفات المرفوعة.
أما على الجانب البرمجي: Docker وDocker Compose v2 (>= 2.20)، واسم نطاق (مثل erp.myapp.com) يشير إلى عنوان IP الخاص بـ VPS، والمنفذ 443 مفتوح للداخل. يستخدم ERPNext MariaDB 10.6+ كقاعدة بيانات رئيسية وRedis للتخزين المؤقت وعمّال الوقت الفعلي — كلاهما مدرج في stack frappe_docker؛ لا تحتاج إلى تثبيتهما بشكل منفصل.
انشر ERPNext مع Frappe Docker وHTTPS
تحضير VPS وDocker
عبر SSH، حدّث النظام (
apt update && apt upgrade -y) وثبّت Docker عبرcurl -fsSL https://get.docker.com | sh. أضف مستخدمك إلى مجموعة docker:usermod -aG docker $USER. تحقّق منdocker compose version(v2 مطلوب).الحصول على frappe_docker
استنسخ المستودع الرسمي واختر الفرع المقابل للإصدار المستهدف:
git clone https://github.com/frappe/frappe_docker cd frappe_dockerيحتوي مجلد
overrides/على compose partials لـ Caddy (HTTPS تلقائي) وTraefik وتطبيق HRMS — اجمعها وفق احتياجاتك.إعداد البيئة
انسخ
example.envإلى.envواضبط المتغيرات الأساسية:cp example.env .envفي
.env، حدّدFRAPPE_SITE_NAME_HEADERوDB_PASSWORDوREDIS_CACHE، وإن كنت تستخدم override Caddy —LETSENCRYPT_EMAILوالنطاق فيCaddyfile. لا تنشر أبدًا بكلمات المرور الافتراضية.تشغيل الحزمة
ابدأ جميع الخدمات:
docker compose --project-name erpnext \ -f compose.yaml \ -f overrides/compose.mariadb.yaml \ -f overrides/compose.redis.yaml \ -f overrides/compose.https.yaml \ up -dثم أنشئ موقع ERPNext وثبّت التطبيق:
docker compose exec backend bench new-site erp.myapp.com \ --mariadb-root-password <rootpwd> \ --admin-password <adminpwd> docker compose exec backend bench --site erp.myapp.com install-app erpnext docker compose exec backend bench --site erp.myapp.com migrateتابع السجلات للتأكد من سلامة جميع الخدمات (db، redis، workers، scheduler):
docker compose logs -f.إعداد الوكيل العكسي
إن لم تكن تستخدم override Caddy المدرج، ضع Nginx أمام ERPNext. مثال مبسّط:
server { listen 443 ssl; server_name erp.myapp.com; ssl_certificate /etc/letsencrypt/live/erp.myapp.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/erp.myapp.com/privkey.pem; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; } }مع Caddy، يكفي
Caddyfileبسيط:erp.myapp.com { reverse_proxy backend:8000 }— تُحصل شهادة Let's Encrypt وتُجدَّد تلقائيًا.التأمين والنسخ الاحتياطي
قيّد المنافذ الداخلية (MariaDB 3306، Redis 6379) على loopback أو شبكة Docker الداخلية. جدوِل نسخًا احتياطية منتظمة بـ
bench backupوخزّنها خارج VPS:docker compose exec backend bench --site erp.myapp.com backup --with-filesتوجد ملفات النسخ الاحتياطي في
sites/erp.myapp.com/private/backups/داخل volume الـsites— انسخها إلى تخزين كائنات خارجي (S3، Garage) للتعافي من الكوارث.أول تسجيل دخول
افتح عنوان تطبيقك وسجّل الدخول باسم المستخدم
Administratorوكلمة المرور المحددة عندbench new-site. احتسب بضع دقائق بعد التثبيت قبل أن يستجيب العنوان — فعمليات الترحيل الأولية تعمل في الخلفية. ثم ينتقل ERPNext إلى معالج الإعداد: اللغة والمنطقة الزمنية والعملة والسنة المالية والشركة.
بعد التثبيت: الشركة والسنة المالية والمستخدمون
بمجرد تسجيل الدخول كـ Administrator، انتقل إلى الإعدادات ← إعدادات النظام لتأكيد المنطقة الزمنية وتنسيق التاريخ، ثم إلى المحاسبة ← دليل الحسابات لتكييف الهيكل مع المعايير المحلية (يوفر ERPNext دلائل حسابات لنحو مئة دولة).
أنشئ شركتك في المحاسبة ← الشركة: أدخل العملة الأساسية والرقم الضريبي وسنة البدء المالية. يُنشئ ERPNext تلقائيًا حسابات الإقفال وقيود الرصيد الافتتاحي.
للمستخدمين، انتقل إلى الإعدادات ← المستخدمون والصلاحيات ← المستخدم: عيّن الأدوار المهنية (Accounts Manager، Stock User، HR Manager…) بدلًا من الصلاحيات مستندًا بمستند. الأدوار قابلة للتجميع: يمكن للمستخدم أن يكون في آنٍ واحد Sales User وPurchase User دون صلاحيات إدارة.
المراقبة والصيانة
يوفر ERPNext عدة نقاط دخول للإشراف على نسخة الإنتاج.
bench doctor هو أمر التشخيص المدمج: يتحقق من حالة عمّال Celery والمجدوِل واتصال Redis. شغّله من الحاوية:
docker compose exec backend bench doctorيظهر العامل المفقود أو الطابور المعلّق فورًا.
سجلات التطبيق — سجلات ERPNext في sites/<site>/logs/ داخل volume الـ sites:
- web.log: أخطاء HTTP وآثار Python من backend Gunicorn;
- worker.error.log: استثناءات عمّال Celery (المهام المجدوَلة، إرسال البريد);
- scheduler.log: دورات المجدوِل.
النسخ الاحتياطي التلقائي — أنشئ مهمة cron على المضيف لتشغيل bench backup يوميًا ونسخ الأرشيفات إلى تخزين بعيد:
0 3 * * * docker compose -p erpnext exec -T backend \
bench --site erp.myapp.com backup --with-files \
&& rclone copy /path/to/backups remote:erpnext-backupsالتحديثات — قبل أي ترقية إلى إصدار رئيسي، قم بنسخة احتياطية كاملة، واقرأ ملاحظات الإصدار، واختبر على نسخة، ثم: bench update --reset داخل الحاوية. تُطبَّق ترحيلات المخطط تلقائيًا، لكن بعض الإصدارات الرئيسية لـ ERPNext تستلزم الترقية إلى أعلى إصدار ثانوي أولًا (مثلًا v14 → v14.x latest قبل الانتقال إلى v15).
استكشاف الأخطاء: المشكلات الشائعة
تعطّل العامل: RedisBroadcastError أو ConnectionRefusedError نحو Redis
خطأ في worker.error.log: redis.exceptions.ConnectionRefusedError: [Errno 111] Connection refused. السبب: توقّف حاوية Redis أو أعادت التشغيل بعد نفاد الذاكرة. تحقّق: docker compose ps redis — إن كانت Exited، أعد تشغيلها بـ docker compose up -d redis ثم أعد تشغيل العمّال. إن تكرر التعطّل، زِد RAM الـ VPS أو قلّل عدد العمّال في common_site_config.json.
ترحيل المخطط متوقف: frappe.exceptions.SchemaChangedError
خطأ أثناء bench migrate: SchemaChangedError: <DocType> has been manually modified. السبب: عُدِّل عمود يدويًا في قاعدة البيانات، ويرفض ERPNext الكتابة فوقه. العلاج: bench --site erp.myapp.com migrate --skip-failing، ثم افحص DocType المعني في الواجهة وأعد تشغيل migrate بدون الراية.
انتهاء مهلة bench: Traceback ... requests.exceptions.ReadTimeout
خطأ أثناء عملية طويلة (استيراد CSV ضخم، إعادة حساب المخزون): ReadTimeout: HTTPConnectionPool. زِد مهلة Gunicorn في common_site_config.json: "gunicorn_workers": 2, "web_timeout": 120. أعد تشغيل خدمة الويب: docker compose restart backend.
رفض اتصال MariaDB: OperationalError: (2003, "Can't connect to MySQL server on 'db'")
خطأ عند bench new-site أو عند بدء تشغيل العمّال. السبب المعتاد: حاوية MariaDB ليست جاهزة بعد أو فشل فحص الحالة. تحقّق: docker compose logs db | tail -20. إن أظهرت MariaDB [ERROR] InnoDB: Page 0 log sequence number، ملفات قاعدة البيانات تالفة — استعِد من آخر نسخة احتياطية. إن كان مجرد تأخير في الإقلاع، انتظر 30 ثانية وأعد الأمر.
موقع فارغ بعد bench migrate: TemplateNotFound
يعرض ERPNext صفحة بيضاء أو خطأ Jinja بعد التحديث. السبب: لم تُعاد بناء الأصول الثابتة. شغّل: docker compose exec backend bench --site erp.myapp.com clear-cache && bench build --app erpnext. قد يكفي إعادة تشغيل حاوية frontend (إن كانت منفصلة).
ERPNext مقابل Odoo Community: متى تختار أيًّا منهما
مرّر الجدول أفقيًا
| المعيار | ERPNext | Odoo Community |
|---|---|---|
| الرخصة | GPL v3 — الكود والوحدات مجانية | LGPL v3 (core) — وحدات Enterprise ملكية |
| الوحدات المدرجة | محاسبة، مخزون، CRM، تصنيع، موارد بشرية — جميعها مجانية | نواة وظيفية؛ الوحدات المتقدمة محجوزة لـ Odoo Enterprise المدفوع |
| اللغة / الstack | Python + Frappe، JS عادي من جانب العميل | Python + OWL (إطار JS داخلي) |
| الواجهة | مكتب تطبيقات، نماذج قابلة للتهيئة بلا كود | عرض kanban/قائمة، studio low-code (Enterprise) |
| تعقيد التثبيت | stack Docker رسمية موثقة توثيقًا جيدًا | Docker متاح، لكن بتجربة مجتمعية أقل |
| المجتمع | نشط على GitHub ومنتدى Frappe؛ قوي في الهند وأفريقيا | واسع جدًا؛ شبكة شركاء كثيفة في أوروبا |
| مثالي لـ | الشركات الباحثة عن ERP مجاني كامل، التصنيع، متعدد العملات | الشركات الراغبة في CRM متقدم أو تجارة إلكترونية Odoo بلا تطوير مخصص |
يتطوّر ERPNext عبر إصدارات كبرى مع ترحيلات للمخطط: قبل كل تحديث، خذ نسخة bench backup كاملة واختبر ترقية الإصدار على نسخة قبل تطبيقه في الإنتاج. يجب أن تتبع الترحيلات بين الإصدارات الكبرى المسار الرسمي (مثلًا v14 → v15 دون تخطي إصدار).
الوثائق الرسمية
للإعدادات المتقدمة والخيارات الخاصة بالأداة، راجع الوثائق الرسمية لـ ERPNext ومستودع frappe_docker. يغطّي هذا الدليل النشر على VPS؛ وتبقى وثائق الناشر المرجع للإعدادات الدقيقة والتحديثات الكبرى وحالات الاستخدام الخاصة.