لماذا Windmill بدلاً من n8n أو Make في 2026
يُمثّل n8n 3.0 منعطفًا حقيقيًا: Docker إلزامي، وحذف أكثر من 30 عقدة، وعقد Code لم تعد تقرأ متغيرات البيئة. يبقى Make خدمةً مغلقة محدودةَ العمليات شهريًا. يسلك Windmill المسار المعاكس: كودك سكريبت من الدرجة الأولى، مُصدَر وقابل للاختبار الوحدوي، ويمكن تشغيله من الطرفية أو الواجهة بالسهولة ذاتها. تضمن رخصة AGPLv3 أن تكون النسخة ذاتية الاستضافة مطابقة وظيفيًا لعرض السحابة — دون ميزات حصرية للمؤسسات في الاستخدام اليومي.
فوائد ملموسة لفرق DevOps والوكالات
- TypeScript وPython أصليان — تعمل السكريبتات في عامل Node.js أو Python دون تحويل أو طبقات وسيطة؛ تُحلَّل تبعيات npm/pip تلقائيًا عند أول تنفيذ.
- محرر ويب مع تنفيذ مباشر — اكتب واختبر وأعد تشغيل سكريبت من المتصفح في ثوانٍ، دون دفع commit أو إعادة تشغيل أي خدمة.
- تعدد المستأجرين مدمج — يدعم نشر واحد مساحات عمل معزولة متعددة، مثالي لوكالة تدير عدة عملاء أو فريق لديه بيئات dev/staging/prod.
- مهام Cron والـ Webhooks دون إضافات — جدولة مهمة بـ
0 9 * * 1-5أو كشف endpoint webhook هو عملية أصلية، وليست إضافة. - متغيرات سرية مشفرة — الأسرار مشفرة بـ AES-256 في القاعدة ولا تظهر في السجلات؛ لكل مساحة عمل نطاق أسرار خاص.
- لا قيود على البائع — جميع السكريبتات والتدفقات والموارد قابلة للتصدير بصيغة JSON/YAML والاستيراد في أي نشر Windmill آخر.
المتطلبات الدنيا بالأرقام
يعتمد Windmill على PostgreSQL للتخزين وعلى عامل أو أكثر للتنفيذ. خادم HTTP خفيف الوزن؛ حِمل العمال هو ما يحدد حجم الخادم. خصص عاملًا واحدًا لكل vCPU متاح ونحو 1 إلى 2 غيغابايت RAM لكل عامل Python نشط.
التكوين الأدنى والموصى به
- الحد الأدنى المطلق — 2 vCPU، 4 غيغابايت RAM، 20 غيغابايت SSD؛ مناسب لمساحة عمل فردية بعامل واحد ومهام متقطعة.
- فريق صغير (موصى به) — 4 vCPU، 8 غيغابايت RAM، 40 غيغابايت SSD؛ يدعم 3 عمال متزامنين وPostgreSQL على المضيف ذاته دون ضغط على الذاكرة.
- فريق أو متعدد العملاء — 8 vCPU، 16 غيغابايت RAM، 80 غيغابايت SSD؛ يدعم 6 إلى 8 عمال ومساحات عمل نشطة متعددة.
- نظام التشغيل — Ubuntu 22.04 LTS أو Debian 12؛ يلزم Docker Engine 24+ وDocker Compose v2.
- الشبكة — IPv4 مخصصة واسم نطاق لشهادة TLS؛ يكشف Windmill المنفذ 8000 افتراضيًا خلف reverse proxy.
النشر بـ Docker Compose في 7 خطوات
تثبيت Docker وDocker Compose v2
على Ubuntu 22.04 أو Debian 12:
curl -fsSL https://get.docker.com | sh && docker compose version. تحقق أن الأمر يعيدDocker Compose version v2.x.x(بدون شرطة). إن كان النظام يحتويdocker-compose(v1)، أزله:apt remove docker-compose.جلب docker-compose.yml الرسمي
أنشئ مجلدًا مخصصًا وحمّل الإعداد المرجعي:
mkdir -p /opt/windmill && cd /opt/windmill && curl -fsSL https://raw.githubusercontent.com/windmill-labs/windmill/main/docker-compose.yml -o docker-compose.yml. يعلن هذا الملف أربعة خدمات:db(PostgreSQL 16)،windmill_server،windmill_worker، وlsp(خادم إكمال الكود).إنشاء ملف .env
يحتاج Windmill إلى متغيرين إلزاميين. أنشئ مفتاحًا عشوائيًا:
openssl rand -hex 32. ثم أنشئ/opt/windmill/.envبالمحتوى:WM_BASE_URL=https://windmill.your-domain.comوWINDMILL_SECRET_KEY=<المفتاح المُنشأ>. لا تُودع هذا الملف أبدًا في Git.ضبط عدد العمال
يبدأ
docker-compose.ymlافتراضيًا بنسخة واحدة منwindmill_worker. لبدء 3:docker compose up -d --scale windmill_worker=3. على VPS بـ 4 vCPU / 8 غيغابايت، 2 أو 3 عمال هو التوازن المثالي.إعداد Nginx كـ reverse proxy مع TLS
ثبّت Nginx وCertbot:
apt install -y nginx certbot python3-certbot-nginx. أنشئ/etc/nginx/sites-available/windmillبكتلةserverتستمع على المنفذ 80 معproxy_pass http://127.0.0.1:8000;وترويسات WebSocket. احصل على الشهادة:certbot --nginx -d windmill.your-domain.com.تشغيل الـ stack وإنشاء مساحة العمل الأولى
شغّل الـ stack:
cd /opt/windmill && docker compose up -d. انتظر 30 ثانية لجاهزية PostgreSQL، ثم افتحhttps://windmill.your-domain.com. تطلب الواجهة إنشاء مساحة عمل — اختر معرّفًا قصيرًا (prod،acme-client) — وتعريف حساب المسؤول.تفعيل إعادة التشغيل التلقائي ومراجعة السجلات
في
docker-compose.ymlتأكد من أن كل خدمة تحتويrestart: unless-stopped. تحقق من سجلات الخادم:docker compose logs -f windmill_server. السطرWindmill server started on port 8000يؤكد أن النسخة تعمل.
الإعداد: مساحة العمل والمتغيرات السرية والـ Crons
بعد تشغيل النسخة، ثمة ثلاثة محاور إعداد يجب إتقانها قبل إنشاء أول سير عمل.
الإعدادات الأساسية بعد التثبيت
- مساحة العمل والصلاحيات — في
Settings → Workspaceحدد المنطقة الزمنية (تُستخدم للـ Crons) وفعّلAuto-approve executionsفقط إن كان جميع الأعضاء موثوقين. - المتغيرات والموارد — تخزّن
Variablesمفاتيح عددية مشفرة. تخزّنResourcesكائنات منظمة مع مخطط JSON (اتصالات قواعد البيانات، بيانات OAuth). - الجداول الزمنية (Crons) — في محرر السكريبت انقر
Add schedule. الصيغة المقبولة هي Cron القياسية بـ 5 حقول. المنطقة الزمنية لمساحة العمل تُطبَّق تلقائيًا. - الـ Webhooks — كل سكريبت يكشف endpoint بالشكل
/api/w/<workspace>/jobs/run/p/<path>. اعتمد التوثيق بـ token مُنشأ منSettings → Tokens. - مزامنة Git — في
Settings → Git Syncاربط مستودع Git لدفع جميع السكريبتات والتدفقات تلقائيًا عند كل تعديل.
مثال كامل لسير عمل Python
سكريبت Python ملموس: يستعلم API خارجي، يُصفّي النتائج ويُدرج الصفوف في قاعدة PostgreSQL عبر مورد Windmill. أنشئ سكريبت Python 3.11 جديدًا وأدخله مباشرةً من المحرر.
سكريبت Python: استيراد API ← تصفية ← PostgreSQL
- إعلان التبعيات — أسطر
# requirements:في رأس السكريبت تخبر Windmill بحزم pip المطلوبة:# requirements:\n# httpx\n# psycopg2-binary. - توقيع الدالة الرئيسية — Windmill يستدعي دائمًا
def main(...). المعاملات تُحقن من الواجهة أو الـ Cron أو جسم الـ Webhook. - استدعاء HTTP بـ httpx —
import httpx; resp = httpx.get(api_url, timeout=10); resp.raise_for_status(); data = resp.json(). يلتقط Windmill الاستثناءات غير المعالجة ويعرضها في سجل التنفيذ. - التصفية والإدراج —
rows = [r for r in data if r.get('active')]; conn = psycopg2.connect(**db); cur.executemany('INSERT INTO items(id, name) VALUES ...', rows); conn.commit(). يُمرَّر الموردdbكـ dict بايثون. - قيمة الإرجاع —
return {'inserted': len(rows), 'source': api_url}. القيمة المُرجَعة تظهر في الواجهة ومتاحة للخطوات التالية في Flow.
التصليب والأمان
احظر المنفذ 8000 في UFW (ufw deny 8000/tcp) — Nginx وحده يصل إليه عبر localhost. أضف ترويسات الأمان في Nginx: add_header X-Frame-Options SAMEORIGIN; add_header X-Content-Type-Options nosniff. هيّئ نسخ احتياطية لـ PostgreSQL: docker exec windmill-db-1 pg_dump -U windmill windmill | gzip > /backups/windmill-$(date +%Y%m%d).sql.gz. فعّل سياسة كلمة المرور في Settings → Security وفرض 2FA لحسابات المسؤولين.
استكشاف الأخطاء — الأخطاء الشائعة
إليك أكثر خمسة أخطاء شيوعًا عند أول نشر لـ Windmill، مع أسبابها الحقيقية وحلولها.
5 أخطاء حقيقية وحلولها
connection refusedعند بدء تشغيل الخادم — حاويةwindmill_serverتبدأ قبل جاهزية PostgreSQL. أضفhealthcheckلخدمةdbوشرطdepends_on: db: condition: service_healthy.- العمال يبقون
IDLEإلى أجل غير مسمى — السبب الكلاسيكي:DATABASE_URLتشير إلىlocalhostبدلاً من اسم خدمة Docker (db). القيمة الصحيحة:postgresql://windmill:windmill@db/windmill. - فشل سكريبتات Python بـ
ModuleNotFoundError— Windmill يحل تبعيات pip عند التشغيل الأول. إن كان العامل بلا اتصال بالإنترنت، يفشل التثبيت صامتًا. افتح المنفذ 443 الصادر لـpypi.org. - الـ Webhook يُرجع 403 Forbidden — السكريبت في وضع
Require approval. عطّله في محرر السكريبت أو استخدم token خدمة بدورexecutor. - Cron لا يُشغَّل في الوقت المتوقع — المنطقة الزمنية لمساحة العمل UTC افتراضيًا. تحقق من الإعداد في
Settings → Workspace → Timezoneوأعد تشغيل:docker compose restart windmill_server.
نحو الإنتاج: قائمة التحقق النهائية
قبل تعريض Windmill لحركة مرور حقيقية أو مهام حرجة، مرّ على هذه القائمة.
نقاط التحقق قبل الانتقال للإنتاج
- TLS صالح وHSTS — تحقق أن
https://windmill.your-domain.comيستجيب دون تحذيرات وأضفStrict-Transport-Security: max-age=31536000. - نسخ احتياطية مختبرة — اصنع dump لـ PostgreSQL، استعده في حاوية اختبار وتحقق من اتصال الواجهة.
- مراقبة العمال — صفحة
Admin → Workersتعرض الحالة في الوقت الفعلي. هيّئ تنبيهًا إن انخفض عدد العمال النشطين دون 1. - تدوير الأسرار — إن فقدت
WINDMILL_SECRET_KEYفالأسرار المشفرة في القاعدة غير قابلة للاسترداد. احفظ المفتاح في مدير أسرار منفصل عن الـ VPS. - إصدار محدد في docker-compose.yml — استبدل
:latestبـ:1.830.0لتجنب التحديثات التلقائية غير المتحكم بها. - Git Sync مفعّل — اربط مستودعًا خاصًا لتنسيق جميع سكريبتاتك وتدفقاتك.
Windmill مقابل n8n مقابل Temporal
مرّر الجدول أفقيًا
| المعيار | Windmill 1.830 | n8n 3.x | Temporal (سحابة/ذاتي الاستضافة) |
|---|---|---|---|
| لغة سير العمل | TypeScript, Python, Go, Bash | JavaScript (عقد) + Code nodes محدودة | Go, Java, Python, TypeScript عبر SDK |
| نموذج النشر | Docker Compose، صورة واحدة | Docker إلزامي منذ v3.0 | Docker أو Temporal Cloud SaaS |
| الرخصة | AGPLv3 (استضافة ذاتية كاملة) | Sustainable Use License (قيود على الوكالات) | MIT (النواة) + عرض سحابة مدفوع |
| المتغيرات السرية (ذاتي الاستضافة) | مضمّنة، مشفرة AES-256 | مضمّنة | مضمّنة (Temporal Namespace) |
| محرر ويب مدمج | نعم — IDE كامل مع إكمال تلقائي | نعم — لوحة بصرية | لا — تطوير محلي فقط |
| تعدد المستأجرين | نعم — مساحات عمل معزولة أصلية | جزئي — يُنصح بنسخ منفصلة | نعم — Temporal Namespaces |
| الحد الأدنى من RAM | 4 غيغابايت (عامل واحد + PostgreSQL) | 2 غيغابايت (SQLite)، 4 غيغابايت (PostgreSQL) | 4 غيغابايت (ذاتي) / غير محدد (سحابة) |
| المدة القصوى لسير العمل | غير محدودة (مهام طويلة الأمد) | محدودة بمهلة العقدة | غير محدودة (متانة الأنشطة) |
| منحنى التعلم | منخفض — كود Python/TS قياسي | منخفض — لوحة بصرية | مرتفع — نموذج أنشطة/إشارات |