حدود الذاكرة والمعالج للحاويات
كيف تضع سقفًا للذاكرة والمعالج لحاوية، ولماذا بدون ذلك تُسقط خدمة واحدة جميع الخدمات الأخرى، وكيف تعرف أن النواة أنهت عملية.
آخر تحديث 23 أغسطس 2026
بشكل افتراضي، يمكن للحاوية أن تستهلك كل الذاكرة وكل الأنوية على الجهاز. على VDS-1 بذاكرة تبلغ غيغابايتين، تنتهي هذه الحالة بشكل متوقع: تنتفخ إحدى الخدمات، ويبدأ النواة بقتل العمليات، وما يسقط ليس تلك الخدمة بل قاعدة البيانات المجاورة لها.
كيفية وضع سقف
services:
app:
image: ghcr.io/example/app:1.5.0
deploy:
resources:
limits:
memory: 768M
cpus: "1.0"
reservations:
memory: 256M
يطبّق Compose إعداد deploy.resources.limits حتى مع الأمر العادي docker compose up -d. والمكافئ لذلك في docker run:
docker run -d --memory 768m --cpus 1.0 --memory-swap 768m <image>
ضبط --memory-swap مساويًا لـ --memory يمنع التبديل: الانهيار الصريح أفضل من جهاز بالكاد يتحرك لساعات.
كم يجب أن تخصص
ابدأ من مستواك واترك للنظام بعض الهامش.
| المستوى | الذاكرة | السقف الإجمالي المعقول للحاويات |
|---|---|---|
| VDS-1 | 2 GB | حتى 1.5 GB |
| VDS-2 | 4 GB | حتى 3 GB |
| VDS-3 | 8 GB | حتى 6.5 GB |
| VDS-4 | 16 GB | حتى 14 GB |
| VDS-5 | 24 GB | حتى 21 GB |
| VDS-6 | 32 GB | حتى 29 GB |
يحتاج النظام وذاكرة التخزين المؤقت للملفات وDocker نفسه إلى الباقي. مجموع حدود يتجاوز مقدار الذاكرة ليس خطأ في الإعداد — بل كارثة تنتظر الحدوث.
أما بالنسبة للمعالج: cpus: "1.0" تعني نواة كاملة واحدة. يمتلك VDS-1 نواة واحدة، لذا لا فائدة تُذكر من تحديد المعالج هناك، لكن على VDS-4 وما فوق يستحق الأمر منع إعداد الخادم من استهلاك الأنوية الست كاملة.
ما الذي يُستهلك فعليًا
docker stats --no-stream
docker stats --no-stream --format "table {{.Name}}\t{{.MemUsage}}\t{{.CPUPerc}}"
free -h
راقب الخدمة ليوم كامل تحت الحمل واضبط الحد عند نحو مرة ونصف من الذروة. الحد الضيق جدًا أسوأ من عدم وجوده: ستُعاد الخدمة للعمل في اللحظة التي تحتاجها فيها أكثر من أي وقت.
تعمل
htopوbtopبملء الشاشة فقط في وحدة تحكم “Screen” (VNC). أما وحدة التحكم النصية فلا تمرر حجم النافذة، إذ تبقى دائمًا 80×24، وتتفكك الواجهة فيها. للقياسات السريعة في وحدة التحكم النصية، استخدمdocker stats --no-streamوfree -h.
كيف تعرف أنها قُتلت بسبب الذاكرة
docker inspect -f '{{.State.ExitCode}} {{.State.OOMKilled}}' <container>
sudo dmesg -T | grep -i -E "out of memory|killed process"
رمز الخروج 137 مع OOMKilled: true حكم قاطع لا لبس فيه. من هناك لديك خياران: ارفع الحد إن كان مضبوطًا على قيمة منخفضة جدًا، أو اكتشف سبب استمرار نمو التطبيق — فتسرب الذاكرة لا يُشفى بإضافة ذاكرة، بل يُؤجَّل فقط.
Java والحالات الخاصة الأخرى
لا تزال آلة Java الافتراضية ترى أحيانًا ذاكرة المضيف بدلًا من حد الحاوية، وتحدد حجم الكومة بهامش غير موجود أصلًا. اضبطه صراحةً:
environment:
JAVA_TOOL_OPTIONS: "-Xmx512m -Xms256m"
ينطبق الأمر نفسه على PostgreSQL (shared_buffers) وأي خدمة لها تجمعها الخاص.
أخطاء شائعة
- عدم ضبط أي حدود إطلاقًا. السبب الأكثر شيوعًا لـ “تجمّد الجهاز، لا شيء يستجيب”.
- الحد موجود، لكن لا يوجد فحص صحة. قُتلت الحاوية ولم تُعد تشغيلها أبدًا. أضف
restart: unless-stoppedوhealthcheck— راجع تحديث الحاويات. - نسيت القرص. حددت الذاكرة، لكن الكتابات تصطدم بسقف: راجع سرعة القرص.