دليل النشر

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

انشر على VPS Cloud ←

دليل عملي

النشر

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

Portainer هو واجهة الويب المرجعية لإدارة Docker وDocker Swarm. بدلًا من حفظ عشرات الأوامر، تُدير حاوياتك وstacks وأحجامك من لوحة تحكم بصرية. إليك كيفية نشره على خادم VPS الخاص بك واستخدامه يوميًا.

10 دقائق للقراءةعدد الخطوات: 11
المحتويات· لماذا تثبّت Portainer على خادم VPS الخاص بك1/10
  1. 01لماذا تثبّت Portainer على خادم VPS الخاص بك
  2. 02ما يبسّطه Portainer يوميًا
  3. 03متطلبات Portainer
  4. 04انشر Portainer في 5 خطوات
  5. 05النشر من Git عبر تحديثات GitOps
  6. 06الإعدادات التي ينبغي معرفتها
  7. 07استكشاف الأخطاء: «Unable to move git repository directory: Target path already exists»
  8. 08الأسباب التي أبلغ عنها المستخدمون (فرضيات لم يؤكدها الناشر)
  9. 09حل بديل حذر في 6 خطوات
  10. 10تثبيت Portainer من متجر ServOrbit

لماذا تثبّت Portainer على خادم VPS الخاص بك

تصبح إدارة Docker من سطر الأوامر مملّة بسرعة عندما تتراكم لديك الحاويات: فالعثور على سجلّات خدمة ما، أو فحص حجم (volume)، أو إعادة تشغيل stack، أو التحقق من استخدام الموارد يتطلب التنقل بين عدة أوامر. يعرض Portainer كل ذلك في واجهة ويب: ترى حالة كل حاوية، وتطّلع على السجلّات المباشرة، وتفتح وحدة تحكم تفاعلية، وتنشر stacks عبر محرّر docker-compose، وتراقب استهلاك CPU/RAM. على خلاف منصة PaaS مثل CapRover أو Dokku، لا يبني Portainer شفرتك: فهو أداة لإدارة بيئة Docker القائمة لديك وعرضها بصريًا. إنه مثالي للفرق التي تريد وصولًا واضحًا وقابلًا للتفويض إلى خادم Docker دون منح وصول SSH للجميع.

ما يبسّطه Portainer يوميًا

  • نظرة شاملة في الوقت الحقيقي على جميع حاوياتك وصورك وأحجامك وشبكاتك.
  • نشر stacks عبر محرّر docker-compose مدمج، دون لمس SSH.
  • سجلّات مباشرة ووحدة تحكم تفاعلية داخل كل حاوية، مباشرةً في المتصفح.
  • إدارة دقيقة للصلاحيات: أنشئ حسابات وفرقًا بوصول محدود.
  • مراقبة استهلاك CPU وRAM والشبكة لكل خدمة.
  • إدارة عدة مضيفي Docker أو عناقيد Swarm من واجهة واحدة.

متطلبات Portainer

Portainer خفيف للغاية لأنه لا يفعل سوى إدارة Docker، دون أداة بناء أو قاعدة بيانات ثقيلة. خادم VPS بذاكرة 1 غيغابايت من RAM ومعالج vCPU واحد يكفي وأكثر لتشغيل Portainer نفسه؛ ثم حدّد حجم خادم VPS وفقًا للتطبيقات التي تنوي استضافتها عليه. مع ذلك، خصّص 20 غيغابايت من قرص SSD لصور Docker. يجب تثبيت Docker Engine مسبقًا (يتصل Portainer بمقبس ‎/var/run/docker.sock). يُنصح باسم نطاق ‎portainer.mydomain.com ومنفذ 443 مفتوح لعرض الواجهة عبر HTTPS. مهم: يمنح Portainer تحكمًا كاملًا في Docker، لذا لا تترك واجهته معرَّضة مباشرةً على الإنترنت دون وكيل عكسي (reverse proxy) ومصادقة قوية. أما المنافذ، فتنشر وثائق التثبيت الحالية المنفذ 9443 (واجهة HTTPS بشهادة موقَّعة ذاتيًا)؛ والمنفذ 8000 (نفق TCP) لا يلزم إلا لوكلاء Edge، والمنفذ 9000 (HTTP) منفذ اختياري موروث من الإصدارات القديمة. نفتح هنا المنفذ 9443 فقط، ولمدة الإعداد فقط.

انشر Portainer في 5 خطوات

  1. جهّز Docker على خادم VPS

    ثبّت Docker إن لم يكن مثبتًا بالفعل: ‎curl -fsSL https://get.docker.com | sh. تحقق بـ docker ps. أنشئ حجمًا مخصصًا لحفظ بيانات Portainer: docker volume create portainer_data.

  2. شغّل حاوية Portainer

    ابدأ Portainer CE: ‎docker run -d -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:lts. تستخدم وثائق التثبيت الرسمية الوسم lts (دعم طويل الأمد)؛ وهو الذي نعتمده لخادم إنتاج بدل latest. تصبح الواجهة متاحة على المنفذ 9443 عبر HTTPS موقَّع ذاتيًا.

  3. أنشئ حساب المسؤول

    اقرأ أولًا رمز الإعداد (setup token) من السجلّات: docker logs portainer، السطر setup_token=. ومنذ الإصدارين 2.43 و2.39.4 تتطلبه أي نسخة جديدة لإنشاء أول مسؤول. ثم افتح ‎https://YOUR_VPS_IP:9443: يجب إنشاء الحساب خلال 5 دقائق من أول تشغيل، وإلا يتوقف Portainer من تلقاء نفسه لأسباب أمنية (رسالة «timed out for security purposes»). في هذه الحالة يمنحك docker stop portainer ثم docker start portainer 5 دقائق إضافية. اختر كلمة مرور قوية (12 حرفًا على الأقل).

  4. اعرضه بشكل سليم عبر وكيل عكسي

    ضع Caddy أو Nginx Proxy Manager أمام Portainer لتقديم الواجهة على ‎portainer.mydomain.com بشهادة Let's Encrypt حقيقية. ثم أغلِق الوصول المباشر إلى المنفذ 9443. انتبه: المنفذ الذي ينشره Docker يتجاوز قواعد ufw (يحوّله Docker قبل السلاسل التي يرشّحها ufw)، لذا لا يكفي ufw deny 9443. أعد إنشاء الحاوية مع ‎-p 127.0.0.1:9443:9443 ليبلغها الوكيل المحلي وحده.

  5. انشر أول stack لك

    في قائمة «Stacks»، انقر «Add stack»، والصق ملف ‎docker-compose.yml في المحرّر (مثلًا تطبيق + PostgreSQL)، سمِّ الـ stack وانقر «Deploy the stack». ينشئ Portainer الحاويات والشبكة والأحجام، وتتابع حالتها في الوقت الحقيقي.

فعّل «Access Controls» في Portainer لتفويض إدارة stack محدد إلى مطوّر دون منحه وصولًا إلى الخادم بأكمله. للمزيد، انشر وكيل Portainer على خادم VPS ثانٍ واربطه بمثيلك الرئيسي: عندئذٍ تدير عدة خوادم Docker من نقطة واحدة. انسخ احتياطيًا بانتظام الحجم portainer_data، الذي يحتوي على مستخدميك ونقاط النهاية (endpoints) وتعريفات stacks، إضافةً إلى مجلدات الـ stacks المنشورة من Git (‎compose/).

النشر من Git عبر تحديثات GitOps

يكفي لصق ملف compose للبدء، لكن الـ stack المرتبط بمستودع Git يُحدَّث وحده ويحتفظ بسجلّه خارج الواجهة. في «Stacks > Add stack» اختر «Git Repository» ثم املأ المصدر والمرجع (الفرع) ومسار ملف compose. يستنسخ Portainer عندئذٍ المستودع في حجم بياناته تحت ‎compose/<id الـ stack>. وهذه الآلية، وحدها، هي موضوع قسم استكشاف الأخطاء أدناه.

الإعدادات التي ينبغي معرفتها

  • المصدر والمرجع و«Compose path»: المستودع والفرع ومسار ملف compose من الجذر؛ و«Additional paths» تدمج ملفات YAML أخرى، كخيارات -f متعددة.
  • «GitOps updates» بالاستعلام الدوري: يتحقق Portainer من المستودع على فترات منتظمة («Fetch interval»).
  • «GitOps updates» عبر webhook: يولّد Portainer عنوان URL يُستدعى من مستودعك أو من GitHub Action لإطلاق التحديث عند الطلب.
  • «Re-pull image»: يعيد سحب الصور عند كل تحديث، مثل --pull=always.
  • «Force redeployment»: يعيد النشر عند كل فترة أو webhook حتى لو لم يتغير المستودع، فيستبدل التعديلات المحلية.
  • زر «Pull and redeploy» في صفحة الـ stack: يجلب آخر commit ويعيد النشر فورًا.

استكشاف الأخطاء: «Unable to move git repository directory: Target path already exists»

العَرَض بدقة: على stack منشور من Git، يفشل «Pull and redeploy» (أو تحديث GitOps التلقائي) بالرسالة Unable to move git repository directory: Target path already exists، ولا تُحدَّث الحاويات. هذه هي المشكلة رقم 10428 في مستودع portainer/portainer، فُتحت في أكتوبر 2023 مع Portainer CE 2.19.1 (مستودع GitHub خاص، عقدة Edge)، ووُصفت بأنها متقطعة: كان إعادة التشغيل أو الانتظار يزيلها أحيانًا. ولا يزال الإبلاغ عنها مستمرًا في 2026.

الحالة في المصدر، بحسب الفحص في 29 أكتوبر 2026: المشكلة ما زالت مفتوحة. تحمل وسم bug وأولوية «2 - High»، وأُسندت إلى مطوّر في Portainer في يوليو 2026، وانتقل وسم الإصدار المستهدف فيها من 3.0.0 إلى 3.1.0 في أكتوبر 2026. لا يوجد pull request مرتبط بها، والإصلاح الوحيد المقترح commit في fork لأحد المستخدمين لم يُدمج قط. إذن لا يوجد إصلاح رسمي في هذا التاريخ: يبقى الحل البديل أدناه ساريًا، ولا ينبغي انتظار إصدار بعينه لحل المشكلة.

الأسباب التي أبلغ عنها المستخدمون (فرضيات لم يؤكدها الناشر)

  • مجلد متبقٍّ <id>-old داخل ‎compose/: أثناء التحديث يبدو أن Portainer يعيد تسمية مجلد الـ stack إلى <id>-old قبل نقل النسخة الجديدة؛ وإن بقي مجلد من محاولة سابقة فشل النقل.
  • نشر مقطوع: حاوية Portainer تجمّدت ثم أُعيد تشغيلها في منتصف النشر، أو صفحة أُعيد تحميلها أثناء «Pull and redeploy»، فتركت الحالة غير متسقة لدى عدة مستخدمين (لم يتمكن المشرف من إعادة إنتاجها بهذه الطريقة).
  • صور ضخمة: اشتبه المُبلِّغ الأول في انتهاء مهلة على stack يضم صورة تقارب 2 غيغابايت.
  • صيغة فبراير 2026: يصبح الخطأ ‎stat /data/compose/61: no such file or directory، أي أن مجلد الـ stack اختفى. لا يفيد الحل البديل أدناه في هذه الحالة.

حل بديل حذر في 6 خطوات

  1. حدّد الـ stack ومعرّفه

    دوّن اسم الـ stack الفاشل ومعرّفه الرقمي، وهو اسم المجلد ‎compose/<id>. لا تلمس مجلد <id> نفسه أبدًا: المقصود وحده هو مجلد <id>-old.

  2. أوقف Portainer وانسخ الحجم احتياطيًا

    أوقف Portainer لتجميد قاعدة بياناته: docker stop portainer. ثم أرشِف الحجم كله: ‎docker run --rm -v portainer_data:/data -v "$PWD":/backup alpine tar czf /backup/portainer_data-before-fix.tgz -C /data .. تأكد من وجود الأرشيف وأنه غير فارغ قبل المتابعة.

  3. اعرض مجلد compose

    اعرض محتواه: ‎docker run --rm -v portainer_data:/data alpine ls -la /data/compose. ابحث عن مجلد اسمه معرّف الـ stack متبوعًا بـ -old (مثل 61-old).

  4. اعزل المجلد المتبقي دون حذفه

    انقله خارج الحجم: ‎docker run --rm -v portainer_data:/data -v "$PWD":/backup alpine mv /data/compose/61-old /backup/. استبدل 61 بمعرّفك. يفيد المستخدمون بأن حذف هذا المجلد يكفي؛ وعزله يعطي الأثر نفسه مع إبقاء طريق للتراجع.

  5. أعد التشغيل وكرّر التحديث

    docker start portainer ثم «Pull and redeploy» على الـ stack. تحقق من أن الحاويات أُعيد إنشاؤها فعلًا بالإصدار الجديد، لا أن رسالة الخطأ اختفت فحسب.

  6. إن استمر الفشل

    إن لم يوجد مجلد -old أو كان مجلد <id> غائبًا، فلا ينطبق هذا الحل البديل. والحل المُبلَّغ عنه حينها هو حذف الـ stack وإعادة إنشائه من Git. قبل ذلك تأكد من أن بيانات تطبيقك في أحجام مسمّاة وانسخها احتياطيًا. لا تستعد أرشيف الخطوة 2 إلا إذا ساء شيء.

الوقاية. ليس أي من هذه التدابير إصلاحًا مضمونًا، فالناشر لم يؤكد السبب: إنها تقلّل فقط فرص ترك مجلد -old خلفك. لا تُعد تحميل الصفحة ولا تُعد تشغيل Portainer أثناء «Pull and redeploy». اسحب الصور الضخمة مسبقًا بـ docker pull لتقصير النشر. بعد كل تحديث فاشل، تحقق فورًا من وجود مجلد -old في ‎compose/. انسخ portainer_data احتياطيًا قبل تحديث Portainer. للخدمة الحرجة، لا تعتمد على زر الواجهة وحده: احتفظ بنشر احتياطي عبر docker compose pull && docker compose up -d على الخادم. تابع المشكلة #10428 لتعرف متى يصل الإصلاح.

تثبيت Portainer من متجر ServOrbit

كل ما سبق يمكن تنفيذه يدويًا، ومن المفيد معرفة كيفية القيام بذلك. وإن كنت تفضّل عدم القيام بذلك، فإن Portainer CE متاح في [متجر ServOrbit](/applications/نشر-التطبيقات-وdevops/portainer) ويُثبَّت على خادم VPS بنقرة واحدة. يُنشر القالب بصورة ‎portainer/portainer-ce:latest عبر Docker Compose، ويُركّب مقبس ‎/var/run/docker.sock وينشئ حجم portainer_data للحفاظ على البيانات — دون الحاجة إلى جلسة SSH للإعداد الأساسي. الواجهة غير منشورة على الإنترنت: يربطها القالب بالعنوان المحلي للخادم (‎127.0.0.1، منفذ HTTP رقم 9000)، فتصل إليها عبر نفق SSH أو بإضافة نطاق مخصص من مساحة العميل. عند أول دخول يرشدك Portainer عبر معالج إعداد لإنشاء حساب المسؤول: وإن طلب رمز إعداد (setup token) فهو في سجلّات الحاوية (docker compose logs، السطر setup_token=). وكأي قالب في المتجر، يُقدَّم كدليل تثبيت، دون دعم للتطبيق نفسه. وإن فضّلت البقاء على فرع الدعم طويل الأمد، فاستبدل الوسم latest بـ lts في ملف compose.

أدِر Docker بصريًا باستخدام Portainer

خادم VPS Cloud من ServOrbit يُسلَّم مع Docker جاهز للاستخدام يتيح لك تثبيت Portainer بأمر واحد وقيادة جميع حاوياتك من واجهة ويب واضحة.