النشر11 دقيقة قراءة

نشر تطبيقات الويب باستخدام Kamal على خادم VPS

‏Kamal (المعروف سابقاً بـ MRSK)، الذي طوّرته شركة 37signals، ينشر التطبيقات المعبّأة في حاويات على خادم VPS أو أكثر مباشرةً من جهازك المحلي، دون الحاجة إلى منظّم ثقيل. منذ الإصدار الثاني الذي صدر في سبتمبر 2024 (مُدرَج افتراضياً في Rails 8 الصادر في نوفمبر 2024)، حلّ ‎kamal-proxy‎ محل ‎Traefik‎ كوكيل عكسي مخصص، وباتت الأسرار مركزيةً في ‎`.kamal/secrets`‎. تنسّق أمر ‎`kamal deploy`‎ بناء صورة Docker ورفعها إلى السجل والتبديل دون توقف في تمريرة واحدة.

لماذا تختار 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

01

تثبيت Kamal على جهازك المحلي

نفّذ ‎gem install kamal‎ (يتطلب Ruby 3.1+)، أو إذا كنت تفضل تجنب Ruby استخدم اختصار Docker: ‎alias kamal='docker run -it --rm -v "${PWD}:/workdir" ...'‎. تحقق من التثبيت بـ ‎kamal version‎ — الإصدار الحالي هو 2.12.0.

02

تهيئة الإعداد في مشروعك

في المجلد الجذر للمشروع نفّذ ‎kamal init‎. سيُنشئ Kamal ملفَّي ‎config/deploy.yml‎ و‎.kamal/secrets‎. أدخل في ‎deploy.yml‎: اسم الخدمة وعنوان الصورة وقائمة الخوادم وإعدادات السجل.

03

إعداد الأسرار ومتغيرات البيئة

أضف ‎.kamal/secrets‎ إلى ‎.gitignore‎. في هذا الملف أعلن الأسرار كمتغيرات shell: ‎KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD‎ أو بقراءتها من 1Password. في ‎config/deploy.yml‎ أشر إليها ضمن ‎env.secret:‎ للقيم الحساسة و‎env.clear:‎ للمتغيرات العادية.

04

إعداد الوكيل وشهادة SSL

في ‎config/deploy.yml‎ أضف قسم ‎proxy:‎ مع ‎host: app.votre-domaine.com‎ و‎ssl: true‎ و‎app_port: 3000‎. سيحصل ‎kamal-proxy‎ تلقائياً على شهادة Let's Encrypt. تأكد من أن سجل DNS يشير إلى IP الخادم قبل هذه الخطوة.

05

تجهيز الخادم (مرة واحدة فقط)

نفّذ ‎kamal setup‎. يتصل Kamal عبر SSH، يثبّت Docker إن لزم، يتحقق من السجل، يُشغّل ‎kamal-proxy‎ وينشر النسخة الأولى من التطبيق. هذا الأمر هو خطوة التهيئة الوحيدة.

06

نشر التحديثات اللاحقة

عند كل تحديث نفّذ ‎kamal deploy‎. يبني Kamal الصورة ويرفعها ويشغّل حاوية جديدة بجانب القديمة، ينتظر نجاح فحص الصحة، يحوّل الوكيل إلى الحاوية الجديدة ويوقف القديمة. العملية مرئية في الوقت الفعلي.

07

التحقق من الحالة وعرض السجلات

‏بعد النشر: ‎kamal app details‎ يعرض الإصدار الجاري على كل خادم، ‎kamal app logs -f‎ يتابع السجلات، ‎kamal app exec 'bin/rails console'‎ يفتح وحدة تحكم داخل الحاوية في الإنتاج.

08

إدارة الملحقات (قاعدة البيانات، الذاكرة التخزينية المؤقتة)

‏أعلن 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 v1Kamal 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‎ حسب اسم المضيف دون إعادة إعداد.

قُد عمليات نشر Kamal الخاصة بك على خادم VPS Cloud من ServOrbit

هيّئ خادم VPS Cloud مع قالب النشر ووصول SSH بالمفتاح: يثبّت Kamal عليه Docker وينشر تطبيقك بلا توقف منذ الأمر الأول.

بحاجة إلى مساعدة؟

تصفّح مركز المساعدة والأسئلة الشائعة، أو تواصل مع فريقنا — معاودة اتصال أو WhatsApp أو بريد إلكتروني. الدعم بـالعربية والفرنسية والإنجليزية.

راسلنا على WhatsAppيُفتح في علامة تبويب جديدة