دليل عملي

stack homelab VPS 2026 : 5 خدمات self-hosted

النشر10 دقائق للقراءةعدد الخطوات: 8

أصبح نشر تطبيق واحد على VPS أمرًا اعتياديًا للمطورين. أما نشر خمسة تطبيقات دفعةً واحدة — مدير ملفات وخزينة كلمات مرور وخادم وسائط ومكتبة صور وأرشيف وثائق — على نفس الـ VPS، بملف Compose واحد وشهادة SSL واحدة، فهو تحدٍّ مختلف. يقدّم هذا الدليل البنية الكاملة لـ stack homelab 2026: كيفية تحديد حجم الخادم، وهيكلة `docker-compose.yml`، وإعداد Caddy لتوجيه كل نطاق فرعي، وتجنّب أكثر الأخطاء شيوعًا عند الإطلاق.

المحتويات· لماذا توحيد خمس خدمات على VPS واحد1/8
  1. 01لماذا توحيد خمس خدمات على VPS واحد
  2. 02ما يقدّمه هذا الـ stack عمليًّا
  3. 03المتطلبات الأساسية: التحجيم والمنافذ
  4. 04النشر خطوةً بخطوة
  5. 05Caddy أم Nginx Proxy Manager أم Traefik: أيّ reverse proxy لهذا الـ stack
  6. 06التقوية الدنيا قبل التعرّض للعموم
  7. 07استكشاف الأخطاء: أكثر أخطاء الإطلاق شيوعًا
  8. 08للتعمّق أكثر

لماذا توحيد خمس خدمات على VPS واحد

لنهج «تطبيق واحد لكل VPS» منطقه: عزل تام، نشر مستقل، ولا خطر للتنافس على الموارد. غير أن له تكلفة حقيقية — خمسة خوادم، وخمس عناوين IP، وخمس تجديدات، وخمس إعدادات nginx، وخمس شهادات TLS للمراقبة. بالنسبة لـ stack شخصي أو فريق صغير، لا تُبرَّر هذه التكلفة إلا إذا كانت التطبيقات تتطلب قدرات استيعاب مختلفة جدًّا أو متطلبات أمان متعارضة.

يشترك ‎Nextcloud وVaultwarden وJellyfin وImmich وPaperless-ngx في كونها تطبيقات حركة مرور معتدلة، يستخدمها مستخدم واحد أو عدد محدود. يستهلك Vaultwarden أقل من 50 MB من ذاكرة RAM في وضع الخمول. يعمل Paperless-ngx بحوالي 200 MB. أما Immich، الأكثر استهلاكًا للموارد عند الراحة خارج وقت التحويل، فيبقى دون 400 MB خاملًا. هذه القياسات موثّقة في مشاريع GitHub المعنية وفي ملاحظات مجتمع self-hosting.

لا يُلغي التوحيد على VPS واحد المخاطرَ، بل يُركّزها. المقابل هو نقطة دخول واحدة يجب تقويتها، وشهادة واحدة للإدارة، وملف Docker Compose مُعرَّف بإصدار يُشكّل وحده التوثيق الكامل للبنية التحتية.

ما يقدّمه هذا الـ stack عمليًّا

  • سيادة على البيانات — تبقى الملفات وكلمات المرور والصور والوثائق على خادمك، تحت مفتاح تشفيرك، دون أي اعتماد على مزوّد سحابي خارجي.
  • شهادة TLS wildcard واحدة — يطلب Caddy ويجدّد تلقائيًّا *.‎your-domain.com عبر تحدّي DNS-01، ليغطّي جميع نطاقات الـ stack الفرعية بإعداد واحد.
  • شبكة Docker داخلية معزولة — لا يكشف أي تطبيق منفذًا للعموم مباشرةً؛ يمرّ كل حركة المرور الواردة عبر Caddy على المنفذين 80 و443، وتتواصل الخدمات عبر شبكة bridge خاصة.
  • volumes مُسمَّاة واستعادة قابلة للتنبؤ — تُعلن كل خدمة بياناتها في Docker volume مُسمًّى (nextcloud_data وvaultwarden_data…)، مما يجعل النسخ الاحتياطية والترحيل قابلَين للتكرار بأمر rsync واحد.
  • تحديثات مستقلة — سحب صورة جديدة لـ Immich لا يُعيد تشغيل Jellyfin ولا Paperless-ngx؛ docker compose up -d --no-deps immich يمسّ الخدمة المعنية فقط.
  • تكلفة ثابتة وقابلة للتنبؤ — يُلغي VPS ذو الموارد الثابتة مفاجآت الفواتير الناجمة عن خدمات السحابة عند ارتفاع حمل تحويل Jellyfin أو تراكم مهام OCR في Paperless-ngx.
  • إمكانية ربط الخدمات — يمكن لـ Nextcloud استخدام Redis وMariaDB الموجودَين مسبقًا في Compose؛ ويشترك Immich في نفس شبكة reverse proxy دون إعداد إضافي.

المتطلبات الأساسية: التحجيم والمنافذ

الحد الأدنى الواقعي لهذا الـ stack في الاستخدام الشائع هو 4 vCPU / 8 GB RAM / 100 GB SSD. يغطّي هذا التحجيم بصمات كل خدمة في وضع الخمول، ويتيح هامشًا لتحويل Jellyfin عند الطلب ومهام OCR في Paperless-ngx، اللذين يمثّلان ذروتَي الحمل الأبرز في الـ stack.

بصمات الخمول المقيسة (لا جلسة نشطة، لا مهمة في الخلفية):

- Nextcloud (‎PHP-FPM + cron): ~300 MB حسب حمل المزامنة.
- Vaultwarden: < 50 MB، صورة Rust مدمجة جدًّا.
- Jellyfin: ~250 MB دون تحويل نشط. في التحويل البرمجي (x264، 1080p): من 1 إلى 2 vCPU عند الذروة.
- Immich (server + microservices): ~350-400 MB في وضع الراحة. يمكن لمهام التعلم الآلي (كشف الوجوه، التصنيف) أن تستهلك حتى 2 GB من ذاكرة RAM حسب الحجم.
- Paperless-ngx (web + worker): ~200 MB. قد يُشبع OCR Tesseract على ملف PDF من 50 صفحة vCPU واحدة مؤقتًا.
- Caddy: < 30 MB.
- قواعد البيانات (MariaDB لـ Nextcloud + Paperless، وRedis): ~200 MB مجتمعَين.

المجموع التقديري في وضع الراحة: ~1.6 GB من أصل 8 GB المتاحة. يستوعب الهامش الذروات ويسمح بإضافة خدمة أخرى دون إعادة تحجيم.

المنافذ التي يجب فتحها على جدار الحماية: 80/tcp و443/tcp فحسب. تبقى جميع المنافذ الأخرى مغلقة — لا تُكشف الخدمات الداخلية مباشرةً.

النشر خطوةً بخطوة

  1. تجهيز الـ VPS

    اتصل بالـ VPS عبر SSH وحدّث النظام: apt update && apt upgrade -y. ثبّت Docker وإضافة Compose: curl -fsSL https://get.docker.com | sh. تحقّق من التثبيت: docker compose version. أنشئ مستخدمًا غير root مخصّصًا وأضفه إلى مجموعة docker: adduser deploy && usermod -aG docker deploy. فعّل UFW بالقواعد الدنيا: ufw allow 22/tcp && ufw allow 80/tcp && ufw allow 443/tcp && ufw enable.

  2. إعداد DNS

    في منطقة DNS الخاصة بك، أنشئ سجل A للنطاق الجذر يشير إلى IP الـ VPS، ثم نطاقات فرعية CNAME أو A لكل خدمة: nextcloud.your-domain.com وvault.your-domain.com وjellyfin.your-domain.com وphotos.your-domain.com وdocs.your-domain.com. إذا كنت تستخدم تحدّي DNS-01 الخاص بـ Caddy للحصول على شهادة wildcard، تأكّد من أن مزوّد DNS لديك يمتلك API مدعومة من الوحدة caddy-dns المناسبة. انتظر انتشار DNS (من دقائق إلى ساعات حسب TTL المُعيَّن).

  3. إنشاء هيكل المجلدات

    أنشئ شجرة المشروع على الـ VPS: mkdir -p /opt/homelab/{caddy,nextcloud,vaultwarden,jellyfin,immich,paperless}. سيحتوي هذا الدليل على ملف docker-compose.yml والـ Caddyfile وملفات البيئة. ستُخزَّن البيانات الدائمة في Docker volumes مُسمَّاة، لا في bind-mounts، لتبسيط النسخ الاحتياطية وتجنّب مشكلات الأذونات.

  4. كتابة الـ Caddyfile

    في ‎/opt/homelab/caddy/Caddyfile، أعلن كتلةً لكل نطاق فرعي. مثال لـ Nextcloud: nextcloud.your-domain.com { reverse_proxy nextcloud:80 }. كرّر النمط لكل خدمة مشيرًا إلى اسم خدمة Docker (vaultwarden وjellyfin وimmich-server وpaperless-webserver). يحصل Caddy على شهادات Let's Encrypt ويجدّدها تلقائيًّا عند أول وصول. للحصول على شهادة wildcard، استبدل الكتل الفردية بـ *.your-domain.com مع وحدة DNS الخاصة بمزوّدك، مُهيَّأةً عبر متغيّرات البيئة لصورة Caddy المخصّصة.

  5. كتابة docker-compose.yml

    أنشئ ‎/opt/homelab/docker-compose.yml بشبكة proxy مشتركة وشبكة internal معزولة. أعلن خدمة Caddy بـ ports: ["80:80", "443:443"] وvolumes: ["./caddy/Caddyfile:/etc/caddy/Caddyfile", "caddy_data:/data"]. لكل تطبيق، أعلن networks: [proxy, internal] ولا تكشف أي ports: — Caddy وحده يكشف منافذ عامة. استخدم depends_on مع condition: service_healthy لمنع Nextcloud من محاولة الاتصال بـ MariaDB قبل أن تصبح جاهزة. تمرّ المتغيّرات الحسّاسة (كلمات مرور قواعد البيانات، المفاتيح السرية) في ملف .env مُشار إليه بـ env_file: .env.

  6. إعداد متغيّرات البيئة

    أنشئ ‎/opt/homelab/.env بالمتغيّرات المطلوبة لكل خدمة: MYSQL_ROOT_PASSWORD وMYSQL_DATABASE وMYSQL_USER وMYSQL_PASSWORD لـ MariaDB؛ وNEXTCLOUD_ADMIN_USER وNEXTCLOUD_ADMIN_PASSWORD وNEXTCLOUD_TRUSTED_DOMAINS لـ Nextcloud؛ وVAULTWARDEN_ADMIN_TOKEN لـ Vaultwarden. ولّد المفاتيح السرية بـ openssl rand -hex 32. لـ Immich، انسخ ملف .env المثالي من المستودع الرسمي. لا تلتزم أبدًا بهذا الملف في مستودع عام؛ أضف .env إلى .gitignore.

  7. تشغيل الـ stack

    من ‎/opt/homelab، نفّذ docker compose pull لتنزيل جميع الصور، ثم docker compose up -d لبدء تشغيل الكل. تابع سجلات الإقلاع بـ docker compose logs -f للتأكد من بدء كل خدمة دون أخطاء. قد تستغرق التهيئة الأولى لـ Nextcloud وPaperless-ngx بضع دقائق (ترحيل قواعد البيانات، توليد المفاتيح). يحصل Caddy على شهادات TLS عند أول وصول لكل نطاق فرعي — تأكّد من إمكانية الوصول إلى المنفذين 80 و443 من الخارج قبل الاختبار.

  8. إتمام إعداد كل خدمة

    ادخل إلى كل واجهة ويب لإتمام الإعداد الأولي: Nextcloud (nextcloud.your-domain.com) لتفعيل التطبيقات الموصى بها (Contacts وCalendar وTalk)؛ وImmich (photos.your-domain.com) لإعداد المكتبات وتفعيل مهام التعلم الآلي في الخلفية؛ وPaperless-ngx (docs.your-domain.com) لإعداد مستهلك الوثائق والـ OCR؛ وJellyfin (jellyfin.your-domain.com) للإشارة إلى مجلدات الوسائط المثبّتة كـ volumes. يحتاج Vaultwarden (vault.your-domain.com) فقط إلى إنشاء حساب من عميل Bitwarden — لا إعداد خادم أوّلي مطلوب.

Caddy أم Nginx Proxy Manager أم Traefik: أيّ reverse proxy لهذا الـ stack

مرّر الجدول أفقيًا

المعيارCaddyNginx Proxy ManagerTraefik
الإعدادCaddyfile تصريحي، إعادة تحميل بدون توقفواجهة ويب، لا ملفات للتحريرLabels Docker، إعادة تحميل تلقائية
SSL تلقائيمدمج، DNS-01 وHTTP-01 أصليّانLet's Encrypt عبر الواجهة، DNS-01 ممكنLet's Encrypt عبر ACME resolver، DNS-01 عبر providers
Wildcardأصلي عبر وحدة caddy-dnsممكن لكنه يتطلب إعدادًا يدويًّاأصلي عبر certificateResolvers
منحنى التعلّممنخفض — Caddyfile مقروء في 10 دقائقمنخفض جدًّا — كل شيء بنقراتمتوسط — توثيق ضخم
مناسب لهذا الـ stackنعم — إعداد مُعرَّف بإصدار، إعادة تحميل مباشرةنعم للبداية، أقل مثالية للإصدارنعم للـ stacks الأكثر تعقيدًا، عبء إعداد هنا

التقوية الدنيا قبل التعرّض للعموم

أربعة إجراءات يجب تطبيقها قبل جعل الـ stack في متناول الإنترنت:

1. عطّل صفحة التسجيل المفتوحة في Vaultwarden بوضع SIGNUPS_ALLOWED=false في ملف .env بمجرد إنشاء حسابك.
2. أضف ترويسة X-Robots-Tag: noindex في Caddyfile لـ Vaultwarden وواجهة إدارة Paperless-ngx — هذه الصفحات لا ينبغي فهرستها.
3. فعّل تدوير سجلات Docker (log-opts في ‎/etc/docker/daemon.json) لمنع سجلات Jellyfin أو Paperless-ngx من ملء القرص.
4. جدوِل docker compose pull && docker compose up -d أسبوعيًّا عبر cron للحفاظ على تحديث الصور — تنشر تطبيقات self-hosting بانتظام تصحيحات أمنية. راجع سجلات التغييرات قبل تحديث Immich الذي قد يُدخل ترحيلات قواعد بيانات غير قابلة للتراجع.

استكشاف الأخطاء: أكثر أخطاء الإطلاق شيوعًا

Error response from daemon: network proxy declared as external, but could not be found — تظهر هذه الرسالة حين لا تكون الشبكة الخارجية المُعلَنة في docker-compose.yml موجودةً بعد. أنشئها يدويًّا قبل أول docker compose up: docker network create proxy. أو حوّل الشبكة إلى داخلية في الـ Compose (أزل external: true) لكي ينشئها Compose بنفسه.

nextcloud.your-domain.com redirected you too many times — يكتشف Nextcloud طلب HTTPS على أنه HTTP لأن Caddy يعيد توجيهه عبر HTTP على الشبكة الداخلية. أضف NEXTCLOUD_TRUSTED_PROXIES بالشبكة الفرعية لـ Docker (مثلًا 172.16.0.0/12) وOVERWRITEPROTOCOL=https في .env. دون هذه المتغيّرات لا يثق Nextcloud بترويسات X-Forwarded-Proto المُرسَلة من Caddy ويحاول إعادة التوجيه إلى HTTPS إلى ما لا نهاية.

Immich cannot connect to database: connection refused — يبدأ Immich قبل أن يصبح PostgreSQL جاهزًا. أضف depends_on مع condition: service_healthy على خدمة immich-server وتأكّد من أن خدمة database تُعلن healthcheck صالحًا (مثلًا pg_isready -U immich). بدون healthcheck يعتبر Docker Compose الخدمة «مشغَّلة» فور إطلاق الحاوية، لا حين تقبل الاتصالات.

Paperless-ngx worker exited with error: celery worker unhealthy — قاعدة بيانات Redis غير متاحة. تحقّق من أن خدمة Redis في نفس شبكة Paperless وأن المتغيّر PAPERLESS_REDIS يشير إلى اسم خدمة Compose (redis://redis:6379)، لا إلى localhost — في Docker Compose يشير localhost داخل الحاوية إلى الحاوية ذاتها، لا إلى خدمة أخرى.

عدم تجديد Caddy لشهادة wildcard — إذا كنت تستخدم تحدّي DNS-01، تحقّق من تمرير متغيّرات بيئة API الـ DNS (token، zone ID) بشكل صحيح إلى خدمة Caddy في Compose. يؤدّي token منتهي الصلاحية أو صلاحية DNS غير كافية إلى فشل التجديد بصمت قبل 30 يومًا من انتهاء الصلاحية — يسجّل Caddy الخطأ لكنه لا يوقف حركة المرور حتى انتهاء الصلاحية الفعلية.

للتعمّق أكثر

يغطّي هذا الـ stack الخدمات الخمس الأكثر طلبًا في إعدادات homelab لعام 2026. لكل منها دليل مخصّص على هذه المدونة إن أردت التعمّق في جانب بعينه: نسخ Nextcloud الاحتياطي، وإدارة ألبومات Immich، وتحويل Jellyfin عتاديًّا، وقواعد الاحتفاظ في Paperless-ngx، أو مزامنة Vaultwarden متعدّد الأجهزة.

للذهاب أبعد من هذا الـ stack، البنى الإضافية المضافة عادةً هي Uptime Kuma (مراقبة الخدمات الداخلية) وNtfy أو Apprise (الإشعارات الفورية). هذه الخدمات خفيفة بما يكفي لإضافتها إلى نفس Compose دون التأثير على التحجيم.

إذا أصبحت إدارة التحديثات والنسخ الاحتياطية عبئًا يدويًّا، يقدّم كلٌّ من Coolify وDokploy واجهات تُؤتمت هذه المهام مع الحفاظ على بنية Docker Compose الأساسية.

VPS بوصول root لـ stack homelab الخاص بك

تقدّم ServOrbit.com خوادم VPS سحابية ابتداءً من 99 درهم/شهر، مع IPv4 مخصّصة واختيار نظام التشغيل (Ubuntu أو Debian أو AlmaLinux) وشبكة عالية التوفّر ولقطات. انشر كامل هذا الـ stack بأمر واحد `docker compose up -d`.

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

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

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