لماذا تختار Kamal بدلاً من Kubernetes لنشر تطبيقاتك على VPS؟
Kubernetes مصمم لحل مشكلات التنسيق على نطاق واسع — اكتشاف الخدمات، التوسع الأفقي التلقائي، مساحات الأسماء لفرق متعددة — وهي مشكلات لا وجود لها على خادم VPS واحد أو مجموعة صغيرة. تستهلك بنيته التحكمية وحدها ما بين 2 و4 غيغابايت من الذاكرة العشوائية قبل تشغيل أي تطبيق. Kamal يستهدف نطاقاً مختلفاً: يأخذ ملف Dockerfile الخاص بك، يبني الصورة، يرفعها إلى السجل، يشغّلها على خوادمك عبر SSH، ويحوّل حركة المرور بلا انقطاع بفضل kamal-proxy. كل الإعداد يتضمن ملف config/deploy.yml واحداً يُحفظ مع الكود. لا بنية تحكم لصيانتها، لا شهادات API للتجديد، لا YAML موزعة على عشرة موارد. تحتفظ ببساطة تشغيل VPS — وصول SSH مباشر، docker ps مقروء، سجلات في ملف — مع الحصول على سير عمل نشر احترافي مع تراجع فوري وفحوصات صحة وHTTPS تلقائي.
ما يقدمه لك Kamal v2
- نشر بدون توقف — ينتظر kamal-proxy نجاح فحوصات الصحة على الحاوية الجديدة قبل تحويل حركة المرور، مع إتمام الطلبات الجارية على الحاوية القديمة
- أمر واحد — ينفذ
kamal deploy البناء والرفع إلى السجل والنشر عبر SSH والتحقق دون تدخل يدوي - HTTPS تلقائي من Let's Encrypt — يتولى kamal-proxy تجديد شهادات TLS؛ لا حاجة لإعداد Certbot منفصل
- تراجع فوري — يُعيد
kamal rollback [VERSION] توجيه الوكيل إلى صورة موجودة مسبقاً على الخادم في ثوانٍ - إدارة أسرار منظمة — يدعم
.kamal/secrets القراءة من 1Password وBitwarden أو متغيرات البيئة دون تخزين قيم نصية في المستودع - دعم متعدد الخوادم والأدوار — خوادم الويب وعمال Sidekiq وملحقات Postgres وRedis في ملف واحد، تُنشر بالتوازي
- تطبيقات متعددة على VPS واحد — منذ Kamal 2، تتشارك عدة تطبيقات في kamal-proxy واحد دون تعارض
- متوافق مع أي تقنية — Rails وDjango وNode.js وGo وPHP: يتطلب Kamal فقط ملف Dockerfile وسجل حاويات
المتطلبات المسبقة قبل النشر باستخدام Kamal
على جانب VPS، يتطلب Kamal نظام Ubuntu 22.04 أو 24.04 (أو أي توزيعة Linux تدعم Docker 20.10 أو أحدث)، وصولاً عبر SSH بمفتاح (لا كلمة مرور)، وما لا يقل عن 2 vCPU و2 غيغابايت من ذاكرة الوصول العشوائي لتطبيق ويب قياسي مع قاعدة بياناته. يمكن لـ Kamal تثبيت Docker بنفسه خلال أول kamal setup، لكن يجب أن يمتلك حساب SSH حقوق sudo. يلزم فتح المنفذَين 80 و443 ووجود سجل DNS من النوع A يشير إلى IP الخادم قبل تفعيل SSL. على جهازك المحلي، ثمة خياران: تثبيت الحزمة gem install kamal (يتطلب Ruby 3.1+) أو استخدام صورة Docker الرسمية. الإصدار الحالي هو 2.12.0 (يونيو 2026). احضر أيضاً سجل حاويات — Docker Hub أو GitHub Container Registry أو سجلاً خاصاً — مع بيانات اعتماده.
Kamal v1 مقابل Kamal v2: ما الذي تغيّر
صدر Kamal 2 في سبتمبر 2024 (مُدرَج افتراضياً في Rails 8 الصادر في نوفمبر 2024)، ليستبدل Traefik بـ kamal-proxy، وكيل عكسي داخلي طوّرته 37signals. التغيير جوهري: Traefik تصريحي (ترسل إليه إعداداً وينسجم معه)، بينما Kamal أمري. كانت النسخة 1 تستطلع واجهة Traefik API باستمرار لمعرفة ما إذا اكتمل النشر — وهو مصدر لسباقات الظروف. مع kamal-proxy، الأوامر مباشرة ومتزامنة. على صعيد الإعداد، يختفي قسم traefik: من deploy.yml ليحلّ محله قسم proxy: بمفاتيح host وssl وapp_port. تنتقل الأسرار من .env إلى .kamal/secrets، وهو ملف shell يمكنه استدعاء أدوات خارجية. تكشف kamal upgrade إعداد v1 وتقترح خطة ترحيل آلية. ويضيف Kamal 2 تشغيل تطبيقات متعددة على وكيل واحد، ووضع الصيانة kamal app pause، ودعماً تجريبياً للنشر التدريجي.
التثبيت والنشر الأول مع Kamal v2
تثبيت Kamal على جهازك المحلي
نفّذ gem install kamal (يتطلب Ruby 3.1+)، أو إذا كنت تفضل تجنب Ruby استخدم اختصار Docker: alias kamal='docker run -it --rm -v "${PWD}:/workdir" ...'. تحقق من التثبيت بـ kamal version — الإصدار الحالي هو 2.12.0.
تهيئة الإعداد في مشروعك
في المجلد الجذر للمشروع نفّذ kamal init. سيُنشئ Kamal ملفَّي config/deploy.yml و.kamal/secrets. أدخل في deploy.yml: اسم الخدمة وعنوان الصورة وقائمة الخوادم وإعدادات السجل.
إعداد الأسرار ومتغيرات البيئة
أضف .kamal/secrets إلى .gitignore. في هذا الملف أعلن الأسرار كمتغيرات shell: KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD أو بقراءتها من 1Password. في config/deploy.yml أشر إليها ضمن env.secret: للقيم الحساسة وenv.clear: للمتغيرات العادية.
إعداد الوكيل وشهادة SSL
في config/deploy.yml أضف قسم proxy: مع host: app.votre-domaine.com وssl: true وapp_port: 3000. سيحصل kamal-proxy تلقائياً على شهادة Let's Encrypt. تأكد من أن سجل DNS يشير إلى IP الخادم قبل هذه الخطوة.
تجهيز الخادم (مرة واحدة فقط)
نفّذ kamal setup. يتصل Kamal عبر SSH، يثبّت Docker إن لزم، يتحقق من السجل، يُشغّل kamal-proxy وينشر النسخة الأولى من التطبيق. هذا الأمر هو خطوة التهيئة الوحيدة.
نشر التحديثات اللاحقة
عند كل تحديث نفّذ kamal deploy. يبني Kamal الصورة ويرفعها ويشغّل حاوية جديدة بجانب القديمة، ينتظر نجاح فحص الصحة، يحوّل الوكيل إلى الحاوية الجديدة ويوقف القديمة. العملية مرئية في الوقت الفعلي.
التحقق من الحالة وعرض السجلات
بعد النشر: kamal app details يعرض الإصدار الجاري على كل خادم، kamal app logs -f يتابع السجلات، kamal app exec 'bin/rails console' يفتح وحدة تحكم داخل الحاوية في الإنتاج.
إدارة الملحقات (قاعدة البيانات، الذاكرة التخزينية المؤقتة)
أعلن Postgres ضمن مفتاح accessories: في deploy.yml. kamal accessory boot db يشغّل الخدمة على الخادم الصحيح. لا تمر الملحقات عبر kamal-proxy بل تتصل بالتطبيق مباشرة عبر متغيرات البيئة.
الإعداد متعدد الخوادم والنشر المتوازي
يُوزّع Kamal النشر على جميع خوادم الدور بالتوازي بشكل افتراضي. لتنظيم نشر تدريجي أضف boot: limit: 2 wait: 10 — سيُنشر Kamal على خادمَين في كل مرة مع فاصل 10 ثوانٍ. تتيح الأدوار تمييز الخوادم: web: لخوادم HTTP وworkers: بأمر مختلف كـ bundle exec sidekiq. لكل دور خوادمه وأسراره ومتغيراته. يعمل kamal-proxy واحد على الخادم الرئيسي، بينما تُشغّل الخوادم الأخرى حاوية التطبيق فحسب.
متغيرات البيئة والأسرار — أفضل الممارسات
الفصل بين المتغيرات الواضحة والأسرار صريح في Kamal 2. في deploy.yml، تذهب المتغيرات غير الحساسة ضمن env: clear:، والأسرار ضمن env: secret: — تُقرأ قيمها من .kamal/secrets وقت النشر وتُحقن في الحاوية دون المرور بأمر shell مرئي. كل دور يجب أن يُدرج الأسرار التي يحتاجها صراحةً. يعرض kamal secrets print القيم المحلولة للتحقق من قراءة مدير كلمات المرور قبل النشر.
إذا أدخل نشر ما انحداراً، لا تنتظر دورة البناء التالية: نفّذ kamal rollback [VERSION] لإعادة توجيه kamal-proxy فوراً إلى صورة موجودة مسبقاً على الـ VPS. استعرض الإصدارات المتاحة بـ kamal app images. لا يعيد التراجع البناء — يُعيد توجيه الوكيل في ثوانٍ.
HTTPS التلقائي مع kamal-proxy وLet's Encrypt
يتولى kamal-proxy دورة حياة TLS الكاملة: يستمع على المنفذ 80، يستجيب لتحديات ACME HTTP-01 من Let's Encrypt، يحصل على الشهادة، يخزّنها في مجلد Docker على الخادم ويجدّدها تلقائياً قبل انتهاء صلاحيتها. الشرط الوحيد أن يحلّ اسم المضيف المُعلن في proxy: host: إلى IP الخادم لحظة أول نشر — تحدي ACME متزامن ويوقف التشغيل إن لم يُحلّ DNS بعد. على الخوادم متعددة التطبيقات، يُدير الوكيل شهادة منفصلة لكل نطاق عبر SNI.
استكشاف الأخطاء — مشاكل شائعة عند النشر باستخدام Kamal
انتهاء مهلة SSH: تحقق من إمكانية الوصول إلى IP الخادم وفتح المنفذ 22، وتشغيل وكيل SSH. فشل فحص الصحة: فحص الصحة الافتراضي يطرق GET /up — أعلن مساراً مختلفاً بـ proxy: healthcheck: path: /health إذا لم يستجب تطبيقك على هذا المسار. تحقق أيضاً من تطابق app_port: مع المنفذ الفعلي. خطأ في مصادقة السجل: نفّذ kamal registry login ثم أعد المحاولة. تعارض المنافذ: إذا شغل عملية خارجية المنفذَين 80 أو 443، لن يبدأ kamal-proxy؛ حدّدها بـ ss -tlnp | grep -E '80|443'. فشل kamal setup عند تثبيت Docker: يجب أن يمتلك حساب SSH حقوق sudo، أو ثبّت Docker يدوياً مسبقاً.
دمج Kamal في خط أنابيب CI/CD مع GitHub Actions
يتضمن سير عمل GitHub Actions النموذجي لـ Kamal 2 مهمتَين: مهمة اختبار (تُشغَّل عند كل push) ومهمة نشر مشروطة (تُفعَّل عند الدفع إلى main أو نشر إصدار). في مهمة النشر: ثبّت Ruby وحزمة Kamal، ثم نفّذ kamal deploy مع حقن الأسرار من GitHub Secrets. العناصر الأساسية في .github/workflows/deploy.yml: مهمة النشر تعتمد على مهمة الاختبار (needs: test)، وتهيّئ متغير KAMAL_REGISTRY_PASSWORD: ${{ secrets.KAMAL_REGISTRY_PASSWORD }}، وتثبّت Kamal بإصدار محدد، ثم تنفّذ kamal deploy. يُعدّ وكيل SSH عبر webfactory/[email protected] مع مفتاح خاص محفوظ في GitHub Secrets.
Kamal v1 مقابل Kamal v2 — ملخص الفروق
| Kamal v1 | Kamal v2 | |
|---|---|---|
| الوكيل العكسي | Traefik (تصريحي، يستطلع API) | kamal-proxy (أمري، أوامر مباشرة) |
| الأسرار | .env في جذر المشروع | .kamal/secrets (shell مُقيَّم، يدعم مديري كلمات المرور) |
| SSL | يُدار عبر Traefik وACME | يُدار عبر kamal-proxy (Let's Encrypt مدمج) |
| تطبيقات متعددة | غير مدعوم بشكل أصلي | أصلي: عدة تطبيقات بوكيل واحد |
| الترقية | — | kamal upgrade يكتشف ويُرحّل إعداد v1 |
| إعداد الوكيل في deploy.yml | قسم traefik: | قسم proxy: مع host وssl وapp_port |
Kamal على VPS ServOrbit — من الأمر إلى النطاق المُشغَّل
يستوفي VPS Cloud من ServOrbit بنظام Ubuntu 24.04 جميع متطلبات Kamal منذ التسليم: وصول SSH بمفتاح، شبكة 1 Gbit/s وعنوان IP مخصص. مسار العمل النموذجي: أنشئ سجل DNS من النوع A يشير إلى app.votre-domaine.com ثم نفّذ kamal setup — يثبّت Kamal Docker ويُشغّل kamal-proxy ويحصل على شهادة Let's Encrypt وينشر تطبيقك في تمريرة واحدة. من تلك اللحظة، كل kamal deploy من طرفيتك أو خط أنابيب CI يُطبّق التحديث دون توقف. لاستضافة مشاريع متعددة على نفس الـ VPS بنطاقات وشهادات مستقلة، أضف تطبيقاً في ملف deploy.yml ثانٍ يشير إلى نفس الخادم — يوجّه kamal-proxy حسب اسم المضيف دون إعادة إعداد.