SSD Nodes Learn 🎉 VPS من $5.50/شهر
الأدلة Matt Connorبقلم Matt Connor

ثبّت Dormice لتشغيل بيئات وكلاء معزولة على VPS

شغّل Dormice على خادم VPS واحد تملكه، مع توافق E2B. تعرّف إلى التثبيت، وتنفيذ الكود، واختبار العزل، وحساب سعة الخادم المطلوبة.

ما هو Dormice وما ليس عليه

Dormice هو sandbox مستضاف ذاتياً للوكلاء: daemon واحد على VPS يعمل بنظام Linux وتملكه أنت، ويستدعيه كود الوكيل عبر HTTP لتشغيل تعليمات برمجية غير موثوقة داخل container معزول. يطلب برنامجك sandbox بالاسم، ويحصل على sandbox نفسه مهما كانت حالته السابقة، ثم يشغّل أمراً داخله ويقرأ الناتج. إنّ sandbox مورد برمجي، وليس جهازاً تسجّل الدخول إليه.

يختلف ذلك عن منح الوكيل حاسوباً كاملاً. إنّ آلة VM مؤقتة لوكيل برمجي هي جهاز تتصل به عبر SSH، وتترك الوكيل يعبث به، ثم تحذفه. يعمل Dormice على مستوى أدنى: إنّه API للتنفيذ يستدعيه برنامجك عندما يكون لديه كود بالفعل ويحتاج إلى مكان آمن لتشغيله. استخدم VM مؤقتة عندما تكون الآلة الكاملة هي وحدة العمل. واستخدم Dormice عندما يكون استدعاء exec واحداً هو وحدة العمل، وتريد تنفيذ مئة استدعاء منه يومياً من دون إنشاء مئة VM.

يصف المشروع نفسه بأنّه متوافق مع E2B. E2B هي خدمة sandbox مستضافة تستورد العديد من أطر عمل الوكلاء مكتبة العميل الخاصة بها. يوفّر Dormice البروتوكول نفسه تحت بادئات URL الخاصة به، لذلك يستمر تطبيق مكتوب باستخدام الحزمة الرسمية e2b في العمل عند توجيهه إلى جهازك الخاص. لا يتغير كود التطبيق. يتغير عنوانا URL وبادئة مفتاح API واحدة.

ما المقصود عملياً بعبارة «SQLite الخاصة ببيئات عزل الوكلاء»

SQLite هي قاعدة بيانات تُضمّنها بدلاً من تشغيل خدمة تديرها، ويستعير Dormice هذا التشبيه مباشرة. برنامج daemon واحد، وملف SQLite واحد للسجل، ومنفذ TCP واحد. لا حاجة إلى Kubernetes أو قاعدة بيانات منفصلة أو مجدول. ينشئ البرنامج daemon قفلاً بجانب سجله، ويرفض البدء عندما يتبين له أن السجل والجهاز لا يمكن أن يكونا متوافقين، لذلك لا يمكن أن يحدث انقسام الدماغ بصمت. الجهاز الواحد هو التصميم المعتمد. إذا كنت تحتاج إلى مجموعة عبر عدة مضيفين، فإن README يطلب منك بوضوح اختيار حل آخر، وينبغي أن تلتزم بذلك.

يتعلق النصف الثاني من الفكرة بالتكلفة. تفرض بيئة العزل المستضافة رسوماً عن كل ثانية تكون فيها موجودة، لذلك تُصمَّم بيئات العزل المستضافة لتكون مؤقتة. يعمل Dormice على أجهزة تدفع تكلفتها مسبقاً، لذلك تكون بيئات العزل فيه دائمة، وتنخفض كلفتها كلما بقيت دون نشاط مدة أطول. تنتقل بيئة العزل إلى حالة خمول تدريجياً: نشطة، ثم مجمّدة، ثم متوقفة، ثم مؤرشفة. يعيد أي طلب acquire تشغيلها من الحالة التي وصلت إليها.

التجميد هو الجزء المهم الذي ينبغي فهمه، لأنه يجعل الاحتفاظ ببيئة عزل لكل وكيل إلى أجل غير محدد أمراً ميسور التكلفة. هذه أرقام المشروع المنشورة، وقد قيسَت على أجهزته، لا على أجهزتك.

ChartOne idle sandbox before and after freezing, figures published by the project
The data behind this chart
[
  {
    "label": "Active, holding 1 GiB",
    "resident_memory_mib": 1024,
    "wake_ms": 0
  },
  {
    "label": "Frozen",
    "resident_memory_mib": 5,
    "wake_ms": 50
  }
]

تنخفض الذاكرة المقيمة لبيئة عزل خاملة من 1024 MiB إلى 5 MiB بعد تجميدها، وتعود للعمل خلال نحو 50 ms. تتوقف العمليات مؤقتاً ثم تستأنف في موضعها، لذلك يحتفظ الوكيل طويل الأمد بحالة shell والعمل غير المكتمل عبر عملية التجميد. أعد إنتاج ذلك على مضيفك قبل أن تبني خطة السعة على هذه الأرقام.

المتطلبات السابقة للتثبيت على المضيف

يجب أن يعمل المضيف بنظام Ubuntu أو Debian على بنية x86_64، ويحتاج المثبّت إلى صلاحيات root. يحتفظ البرنامج الخفي بصلاحيات root أثناء التشغيل لأنه ينفّذ loop mounts ويكتب إلى cgroups.

تعمل بيئات العزل ضمن Docker باستخدام gVisor، وهو وقت تشغيل للحاويات يضع نواة تعمل في مساحة المستخدم بين الحاوية ونواة المضيف. ويوفّر ذلك وقت التشغيل runsc الذي تستخدمه كل بيئة عزل. يتطلب البرنامج الخفي Node 22 أو إصداراً أحدث، ويثبّت المثبّت نسخته الخاصة، لذلك لا يغيّر Node الموجود على النظام.

يجب أن تكون swap موجودة، ويجب أن تكون قيمة vm.swappiness هي 100. هذا متطلب وظيفي، وليس نصيحة لضبط الأداء. تعمل عملية التجميد على دفع ذاكرة بيئة العزل الخاملة إلى swap. ويحتفظ gVisor بذاكرة بيئة العزل كذاكرة مشتركة، ولن تنقل النواة الذاكرة المشتركة إلى swap عند قيمة swappiness الافتراضية. قاس المشروع استعادة 0 بايت عند القيمة الافتراضية، واستعادة 99.5 بالمئة عند القيمة 100. تحقّق من القيمة التي تستخدمها النواة فعلياً، لأن بعض صور السحابة تضبط vm.swappiness = 0 في ملف لن يخطر ببالك قراءته.

sysctl vm.swappiness
swapon --show

يجب أن يطبع sysctl vm.swappiness القيمة vm.swappiness = 100، ويجب أن يعرض swapon --show ملف swap. إذا طبعت swappiness القيمة 0، فلن يفعل كل تجميد شيئاً، وستظل تدفع تكلفة الذاكرة الكاملة لكل بيئة عزل خاملة.

تثبيت Dormice على Ubuntu

التثبيت الموثّق هو تمرير واحد إلى bash:

curl -fsSL https://raw.githubusercontent.com/BitMiracle-AI/Dormice/main/deploy/install.sh | bash

نزّل هذا الملف واقرأه قبل تشغيله. يعمل هذا البرنامج النصي بصلاحية root ويعيد ترتيب المضيف: يثبّت Docker إذا لم يكن موجوداً، وينزّل gVisor وCaddy مع التحقق من checksums، وينشئ swapfile، ويكتب وحدات systemd، ويضيف قواعد إلى الجدار الناري.

curl -fsSL https://raw.githubusercontent.com/BitMiracle-AI/Dormice/main/deploy/install.sh -o dormice-install.sh
less dormice-install.sh
sudo bash dormice-install.sh --swap-gb 8

يحدّد --swap-gb حجم swapfile، وقيمته الافتراضية هي 16، وهذا يستهلك مساحة كبيرة من قرص VPS صغير. يبدّل --mirror cn مصادر التنزيل إلى مرايا يمكن الوصول إليها من بر الصين الرئيسي. تؤدي إعادة تشغيل المثبّت إلى ترقية الشفرة وإصلاح الاختلافات، ولا يدوّر أبداً API token الخاص بك.

تُوضع الشفرة في /opt/dormice، والإعدادات في /etc/dormice/env، وبيانات sandbox في /var/lib/dormice، بينما تُوضع أوامر dormice وdor في /usr/local/bin. ينشئ المثبّت API token أثناء التثبيت ويكتبه في /etc/dormice/env بالوضع 600.

لا توجد release ذات وسم يمكن التثبيت عليها. في 4 August 2026، لا يحتوي المستودع على git tags ولا على GitHub releases، لذلك يستنسخ المثبّت main، وتحصل على كل ما أُضيف في ذلك الصباح. لذلك يعني تثبيت إصدار معيّن تدوين commit الذي ثبّتَّه فعلياً.

git -C /opt/dormice rev-parse HEAD

احفظ hash هذا مع ملاحظات النشر. عندما تؤدي ترقية إلى تعطيل شيء ما، يكون ذلك commit طريقك الوحيد للرجوع، لأنه لا يوجد رقم إصدار تطلبه.

ينهي المثبّت عمله بتشغيل dor doctor، وهو فحص للمضيف للقراءة فقط، حيث يشغّل حاويات gVisor فعلية لإثبات عمل runtime بدلاً من الوثوق بقائمة الحزم. شغّله مرة أخرى كلما تصرّف daemon بطريقة غير سليمة.

sudo dor doctor
systemctl is-active dormice

يجب أن يطبع systemctl is-active dormice القيمة active. إذا طبع failed، فإن journalctl -u dormice -n 50 يحتوي على السبب، ويكون فشل التشغيل عادةً ناتجاً عن متطلب swap أو gVisor، لا عن daemon نفسه.

يثبّت المثبّت Caddy أيضاً على الخادم، لذلك افحص ما يستمع على المنافذ قبل أن تقرر أن إعداد الجدار الناري اكتمل.

sudo ss -lntp

يرتبط daemon بالعنوان 127.0.0.1:3676، ولا يوجد إعداد لتغيير ذلك، وهذا مقصود. يتطلب الوصول إليه من حاسوبك المحمول إجراءً متعمداً، والطريقة الأبسط هي نفق SSH.

ssh -L 3676:127.0.0.1:3676 root@your-server

عند فتح النفق، تكون http://127.0.0.1:3676/console على حاسوبك المحمول هي وحدة التحكم على الويب. سجّل الدخول باستخدام token مرة واحدة، ثم يتحول إلى session cookie من نوع httpOnly، لذلك لا يُخزَّن token نفسه في مكان يمكن للصفحة قراءته. تطبع صفحة Connect هناك مقتطفات عميل جاهزة للنسخ واللصق، وموجّهة مسبقاً إلى endpoint الخاص بك.

إنشاء بيئة معزولة وتنفيذ التعليمات البرمجية فيها

تنشئ عملية واحدة بيئة معزولة: acquire. وهي idempotent، لذلك يعيد المفتاح نفسه البيئة المعزولة نفسها دائماً، مع إنشائها أو إيقاظها أو تشغيلها أو استعادتها حسب الحاجة. أما كل verb آخر فيعيد 404 للمفتاح الذي لم يسبق له رؤيته. لا يحتوي CLI الخاص بـ dor على verb باسم acquire، لذلك تنشئ بيئتك المعزولة الأولى من وحدة التحكم أو من مكتبة عميلة.

يُعد مسار وحدة التحكم الأسرع. افتح /console عبر النفق وأنشئ بيئة معزولة باسم my-agent. بعد ذلك يعمل CLI عليها.

sudo grep DORMICE_API_TOKEN /etc/dormice/env
export DORMICE_ENDPOINT=http://127.0.0.1:3676
export DORMICE_API_TOKEN=paste-the-value-here
dor sandbox ls
dor sandbox exec my-agent 'python3 --version'

يسرد dor sandbox ls كل بيئة معزولة مع حالة دورة حياتها، ما يتيح لك monitor انتقالها من active إلى frozen. يطبع dor sandbox exec إصدار Python 3.12، لأن الصورة الافتراضية هي Ubuntu 24.04 وتتضمن Python 3.12 وNode 24 وgit وripgrep مثبتة مسبقاً. أما ظهور خطأ مصادقة فيعني أن سطر الرمز المميز الذي نسخته تضمّن اسم المتغير.

تنقل الملفات باستخدام dor sandbox push my-agent ./script.py، الذي يضع الملف في /home/user/script.py، ويعيد dor sandbox pull my-agent notes.txt ملفاً إلى النظام. تحدّ أوامر الملفات الأصلية حجم كل ملف إلى 16 MiB، بينما تدعم واجهة الملفات في E2B التدفق، ويصبح حد حصة القرص الخاصة بالبيئة المعزولة هو القيد الوحيد.

الإتلاف هو verb الوحيد الذي يفقد البيانات، وهو يوضح أيضاً قدم المشروع: يوثّق README الرئيسي وagent skill المضمّن dor sandbox destroy <key>، بينما يوثّق README الخاص بحزمة CLI dor sandbox release <key>. شغّل dor sandbox --help على الإصدار الذي بنيته بنفسك، واعتمد على نتيجته بدلاً من ذلك.

وجّه شفرة E2B الحالية إلى خادمك

هذا هو سبب أهمية ذلك. تتصل حزمة e2b الرسمية من npm، من دون تعديل، بـDormice. شغّل هذا من حاسوبك المحمول مع إبقاء نفق SSH مفتوحاً، حتى لا يبدأ أي شيء جديد بالاستماع على الخادم.

npm init -y
npm i e2b tsx
import { Sandbox } from 'e2b';

const sbx = await Sandbox.create({
  apiKey: `e2b_${process.env.DORMICE_API_TOKEN}`,
  apiUrl: 'http://127.0.0.1:3676/e2b/api',
  sandboxUrl: 'http://127.0.0.1:3676/e2b/envd',
});

const result = await sbx.commands.run('python3 -c "print(6 * 7)"');
console.log(result.exitCode, result.stdout);

await sbx.kill();
DORMICE_API_TOKEN=paste-the-value-here npx tsx index.ts

تعرض العملية السليمة رمز الخروج 0 و42. مفتاح API هو الرمز المميز الخاص بك في Dormice، مع إضافة البادئة e2b_ إليه. هذه هي الصيغة التي تتوقعها طبقة التوافق.

التوافق ليس مجرد هيكل تجريبي. تختبر مجموعة الاختبارات الشاملة للمشروع بث stdout وstderr، والأوامر التي تعمل في الخلفية، وPTY تفاعلياً، وعناوين URL موقعة للرفع والتنزيل، ومراقبة الأدلة، ووكيل المنافذ، وكل ذلك عبر الحزمة الرسمية وباستخدام Docker وgVisor daemon فعليين. توجد بعض الاختلافات المهمة التي ينبغي فهمها قبل ترحيل أي شيء فعلي:

  • إنشاء القوالب غير مطبّق. القالب هو docker image تنشئه بنفسك وتسجله باستخدام dor template add، ثم يحل Sandbox.create('name') اسمه. يعيد الاسم غير المسجل 404 بدلاً من التظاهر بوجوده.
  • تحصل Sandboxes التي تُنشأ عبر واجهة E2B على مهل زمنية فعلية، لأن دلالات E2B تتطلب ذلك. لا تُفرض المهل الزمنية مطلقاً على Sandboxes التي تُنشأ عبر native API.
  • تحتفظ Sandbox المجمّدة بعملياتها وتستأنفها من موضع توقفها. لذلك لا تعني الإيقاف والاستئناف هنا الإيقاف ثم البدء البارد الذي قد تكون معتاداً عليه.

ما الذي يمنعه sandbox وما الذي لا يمنعه

يعترض gVisor استدعاءات النظام الصادرة من الحاوية في مساحة المستخدم، ويتولى خدمتها بنفسه. لذلك لا تتواصل الشفرة المشغّلة داخل sandbox مباشرةً مع نواة المضيف. تعمل جميع العمليات داخل sandbox بحساب غير مميّز، وهو uid 1000. يعالج هذا المزيج الحالة المعتادة: إذا شغّلت شفرة مولَّدة rm -rf /، أو ملأت القرص، أو أنشأت عمليات فرعية بلا توقف حتى يتعطل شيء ما، فإن الضرر يقتصر على sandbox نفسها.

لكن هناك أموراً لا يمنعها. وعليك التعامل مع كل منها.

  • يتوفر لـsandbox اتصال شبكي صادر. يمكن للشفرة المولَّدة تنزيل أي شيء تريده وإرسال أي بيانات تعثر عليها. تغطي تقوية الشبكة في أداة التثبيت أمرين محددين: فهي تمنع حركة الحاويات إلى خدمة cloud metadata ضمن النطاق 169.254.0.0/16، حيث تسلّم السحابة بيانات اعتماد المثيل إلى أي جهة يمكنها الوصول إليها، كما تعطل الاتصال بين الحاويات باستخدام "icc": false في daemon.json الخاص بـDocker. ولا شيء آخر محظور. اقرأ sudo iptables -S DOCKER-USER وأضف قواعد DROP الخاصة بك للنطاقات الخاصة التي لا ينبغي لـsandbox الوصول إليها.
  • يدرج Docker قواعده الخاصة قبل قواعد جدار الحماية، لذلك قد يستجيب منفذ حاوية منشور من الإنترنت بينما يصرّ ufw على أنه مغلق. اقرأ كيفية نشر Docker للمنافذ متجاوزاً ufw وأساسيات جدار حماية ufw لخادم VPS قبل تعريض أي شيء على هذا المضيف.
  • gVisor نواة تعمل في مساحة المستخدم، وليس hypervisor. وهذا اختيار مقصود، لأن التجميد يتطلب أن تكون sandboxes عمليات، كما أن اشتراط KVM سيمنع تثبيت البرنامج في أي مكان. إذا كان نموذج التهديد لديك يتطلب المحاكاة الافتراضية العتادية، فاستخدم عزلاً من فئة Firecracker وتقبّل التكلفة التشغيلية المصاحبة له.
  • يمثّل رمز API حد الأمان الكامل من جهة العميل. يمكن لأي جهة تملك DORMICE_API_TOKEN إنشاء كل sandbox على الجهاز وقراءتها وتدميرها. امنح عملية agent الخاصة بها حساب مستخدم بصلاحيات أقل على VPS، وتعامل مع الرمز بالطريقة نفسها التي تتعامل بها مع مفتاح SSH. وتنطبق مباشرةً الممارسات الواردة في تشغيل Claude Code بأمان على VPS.

يعمل daemon نفسه بصلاحية root على المضيف. يحمي gVisor المضيف من الشفرة الموجودة داخل sandbox، ولا توجد حماية للمضيف من daemon أو من أي شخص يملك رمزه. لذلك يجب أن يكون الجهاز الذي يشغّل Dormice مخصصاً لهذا الغرض فقط. وإذا كان agent لديك يصل أيضاً إلى أدوات عبر MCP (بروتوكول سياق النموذج)، فأبقِ خوادم MCP على VPS منفصل للسبب نفسه.

كم عدد بيئات العزل التي تتسع لها سعة 4 GB و8 GB؟

يستهلك الذاكرة شيئان: الاستهلاك الأساسي للخادم نفسه، ومجموعة العمل لكل بيئة عزل قيد التشغيل حالياً. خصص نحو 1 GB لـUbuntu وDocker والـdaemon، ثم اقسم السعة المتبقية على ما تستهلكه إحدى بيئات العزل فعلياً. تستهلك بيئة عزل تشغّل نص Python يقرأ بضعة ملفات نحو 200 إلى 300 MiB. أما البيئة التي تشغّل compiler أو مجموعة اختبارات كاملة فقد تتجاوز 1 gibibyte.

ChartConcurrent sandboxes by host RAM, arithmetic after a 1 GB host reserve
The data behind this chart
[
  {
    "host": "4 GB VPS",
    "active_at_512_mib": 6,
    "active_at_1_gib": 3,
    "frozen_on_16gb_swap": 16
  },
  {
    "host": "8 GB VPS",
    "active_at_512_mib": 14,
    "active_at_1_gib": 7,
    "frozen_on_16gb_swap": 16
  }
]

تستوعب VPS بسعة 4 GB نحو 6 من بيئات العزل قيد التشغيل في الوقت نفسه إذا كانت كل واحدة تستهلك 512 MiB، أو 3 إذا كانت كل واحدة تستهلك gibibyte كاملة. وترفع VPS بسعة 8 GB ذلك إلى 14 و7. هذه حدود للتشغيل المتزامن، وهي ناتجة عن حساب حسابي وليست نتيجة اختبار أداء، لذلك راقب free -m أثناء تشغيل حملك الفعلي.

تُحدَّد بيئات العزل المجمّدة بسعة swap بدلاً من RAM، وهذا هو الهدف الأساسي من التصميم. تحتفظ بيئة عزل مجمّدة كانت تستهلك gibibyte بسعة تقارب ذلك في swap، ولا يبقى منها في الذاكرة الفعلية إلا القليل تقريباً، ولذلك يتيح ملف swap الافتراضي بسعة 16 GB في المُثبّت إيقاف نحو 16 منها. بعد ذلك تحتاج إلى الوصول إلى حالة الإيقاف، حيث لا تستهلك إلا مساحة القرص. مساحة القرص هي الحد الفعلي على المدى الطويل هنا: تحتفظ كل بيئة عزل بنظام ملفاتها، وستملأ بضع عشرات من الوكلاء، يحمل كل منها دليلاً node_modules، وحدة تخزين صغيرة قبل أن تصبح الذاكرة عاملاً مهماً.

التجميد والإيقاف والأرشفة: إعدادات دورة الحياة

الإعدادات الافتراضية هي التجميد بعد 10 دقائق من الخمول، والإيقاف بعد 3 أيام، والأرشفة بعد 7 أيام عند إعداد الأرشفة. يؤدي ضبط stopAfterSeconds على null إلى توفير agent مقيم: قد يتجمّد عند الخمول، لكنه لا يبدأ تشغيله من الصفر أبداً.

الأرشفة اختيارية، ويعالجها daemon بوضوح. اضبط متغيرات DORMICE_S3_* الأربعة، وسيُضغط قرص sandbox متوقف باستخدام tar وzstd، ثم يُرسل إلى أي bucket متوافق مع S3 وتُحرَّر مساحته محلياً. يمكن أن يكون ذلك الـbucket على MinIO تستضيفه بنفسك على جهاز آخر تملكه. إذا تركت المتغيرات دون ضبط، فستبقى sandboxes متوقفة إلى الأبد، وسيُرفض أي policy يطلب الأرشفة بدلاً من تجاهله بصمت. وتظهر عمليات الاستعادة بدلاً من حدوثها بصمت: يجيب الاستحواذ التالي فوراً بحالة استعادة وقيمة تقدّم، ثم تتحول الحالة إلى جاهزة بعد استعادة القرص.

هل ينبغي الاعتماد عليه الآن؟

الإجابة المباشرة: لا، ليس لأي شيء لا يمكنك إعادة بنائه. يعود أول commit في المستودع إلى 8 July 2026. وحتى 4 August 2026، لديه 446 نجمة و37 fork وترخيص Apache-2.0، ولا توجد له أي إصدارة موسومة على الإطلاق. ويذكر سطر الحالة في README نفسه أن لا شيء فيه جاهز للاستخدام في بيئة الإنتاج.

ينطوي هذا المزيج على شكل محدد من المخاطر. يتغير الكود باستمرار، لأن المثبّت يتتبع main. وما زالت الواجهة قيد الاستقرار، ولهذا تحديداً يحمل فعل الحذف اسمين مختلفين في ملفين داخل المستودع نفسه. كما يمكن لمشروع عمره أربعة أسابيع أن يتوقف ببساطة، إذ لا يُلزم أي بند في الترخيص أحداً بالاستمرار.

ما يجعل هذا الخطر قابلاً للاحتواء هو توافق E2B. يتصل تطبيقك ببروتوكول له تنفيذ مستضاف خلفه، لذلك إذا توقف Dormice يمكنك تغيير عنواني URL ومواصلة العمل. اكتب agent الخاص بك مقابل واجهة E2B بدلاً من API الأصلية، وستحتفظ بمسار الخروج هذا. كما أن حزمة @dormice/sdk الأصلية ليست متاحة على npm بعد، لذا يتطلب استخدامها بناؤها من المستودع، وهذا سبب ثانٍ للبدء بالمسار المتوافق.

شغّله في مكان يمكنك تحمّل فقدانه. أعد بناء المضيف من script، وأبقِ token خارج كل prompt وكل commit، وانقل أي شيء يستحق الاحتفاظ به من sandboxes وفق جدول النسخ الاحتياطي الخاص بك.

FAQ

هل Dormice جاهز للاستخدام في بيئة الإنتاج؟

لا، والمشروع يذكر ذلك صراحةً. يوضح سطر الحالة في README أن أياً من مكونات المشروع ليس جاهزاً للاستخدام في بيئة الإنتاج بعد. وحتى 4 August 2026، كان عمر المستودع نحو أربعة أسابيع، من دون وسوم git أو إصدارات، لذلك لا يوجد رقم إصدار يمكن تثبيته. يستنسخ المُثبّت فرع main، ما يعني أن كل تشغيل يجلب أحدث commit. سجّل git -C /opt/dormice rev-parse HEAD بعد كل عملية تثبيت، واحتفظ بأي بيانات مهمة خارج بيئات العزل.

ما الفرق بين Dormice ومنح agent جهاز VM مؤقتاً؟

جهاز VM المؤقت هو جهاز تنشئه لجلسة واحدة عبر SSH ثم تحذفه بعدها. أما Dormice فهي API للتنفيذ: يستدعي برنامجك acquire ثم exec، ويحصل على stdout ورمز الخروج من دون وجود جلسة shell وسيطة. يناسب VM المستخدم أو agent الذي يحتاج إلى حاسوب كامل لفترة من الوقت. أما Dormice فتناسب تطبيقاً يشغّل code مُولّداً مرات عديدة يومياً ولا يريد تنفيذ إعداد جهاز كامل وإزالته لكل عملية تشغيل.

هل يعمل E2B SDK الرسمي فعلاً من دون تغييرات في code؟

نعم، مع إجراء تغييرات في الإعدادات. وجّه apiUrl وsandboxUrl إلى /e2b/api و/e2b/envd على daemon الخاص بك، وأرسل token الخاص بـDormice مع بادئة e2b_ باعتباره مفتاح API. يغطي الاختبار الشامل للمشروع، عبر الحزمة الرسمية، تنفيذ الأوامر وجلسات PTY ونقل الملفات وعناوين URL الموقّعة ووكيل المنافذ. أما إنشاء القوالب فهو الفجوة الأساسية: لم يُنفّذ e2b template build، لذلك يكون القالب docker image تنشئه وتسجّله باستخدام dor template add.

كم عدد بيئات العزل التي يمكن تشغيلها على VPS بسعة 4 GB؟

يمكن تشغيل نحو 6 بيئة عزل نشطة في الوقت نفسه إذا استخدمت كل بيئة 512 MiB، أو 3 إذا استخدمت كل منها gibibyte كاملاً، بعد حجز نحو 1 GB لنظام التشغيل وDocker وdaemon. ويحد swap عدد بيئات العزل المجمدة بدلاً من ذلك. لذلك يمكن لملف swapfile الافتراضي بسعة 16 GB الذي ينشئه المُثبّت أن يستوعب نحو 16 بيئة عزل، إذا كانت كل واحدة منها قد استخدمت gibibyte واحداً. قِس العدد في بيئتك باستخدام free -m تحت حمل فعلي، لأن بيئة عزل تشغّل مجموعة اختبارات قد تستخدم عدة أضعاف ما تستخدمه بيئة تشغّل script صغيراً.

لماذا يحتاج Dormice إلى ضبط vm.swappiness على 100؟

يعني تجميد بيئة العزل دفع الذاكرة غير النشطة الخاصة بها إلى swap. يحتفظ gVisor بذاكرة بيئة العزل باعتبارها shared memory، ولن تنقل نواة Linux الذاكرة المشتركة إلى swap عند قيمة swappiness الافتراضية. لذلك لا يستعيد التجميد أي ذاكرة عند القيمة الافتراضية، وتستمر بيئة العزل في استهلاك كامل الذاكرة. قاس المشروع استعادة 0 bytes عند القيمة الافتراضية و99.5 percent عند ضبطها على 100. تحقّق من القيمة الفعلية باستخدام sysctl vm.swappiness بدلاً من قراءة ملفات الإعداد، لأن بعض صور cloud تأتي بقيمة 0.