كيفية استضافة sandboxd على VPS وتشغيله ذاتيًا
شغّل sandboxd على خادمك عبر تثبيت إصدار محدد، ومفاتيح النماذج، وروابط HTTPS للمعاينة، مع معرفة الحد الأدنى للذاكرة والقرص وحذف صناديق الاختبار القديمة.
ما هو sandboxd، وما الذي تحصل عليه عند تشغيله بنفسك
لاستضافة sandboxd ذاتياً، تحتاج إلى خادم Linux واحد يحتوي على Docker واسم نطاق. ترسل مطالبة، فيبني وكيل برمجي تطبيقاً فعلياً داخل حاوية معزولة، ثم يصبح التطبيق متاحاً على عنوان URL للمعاينة خاص به. تُعد أدوات تحويل المطالبات إلى تطبيقات الفئة الأبرز في الاستضافة لعام 2026، وsandboxd هو النظام الذي يعمل على VPS الخاص بك، بموجب ترخيص MIT، بينما يبقى الرمز البرمجي المُولَّد على القرص الخاص بك.
التصميم صغير عمداً. تدير طبقة التحكم المكتوبة بلغة Go Docker، ويوجّه Traefik v3 كل اسم مضيف للمعاينة، وتحتفظ SQLite بالحالة، ويعمل كل تطبيق داخل حاوية واحدة. لا يوجد Kubernetes ولا خادم قاعدة بيانات منفصل، ولذلك يستطيع خادم بسعة 2 vCPU تشغيله أصلاً.
تحمل أربعة كائنات النموذج بأكمله. التطبيق هو المشروع الدائم، ويحتوي على اسمه وبيانات git الوصفية والأسرار الخاصة به. صندوق الاختبار هو حاوية Docker التي يعمل فيها التطبيق، ويشير كل تطبيق إلى صندوق اختبار واحد في كل مرة. مساحة العمل هي ملفات التطبيق، وتوجد على المضيف وتبقى بعد إزالة الحاوية. المهمة هي مطالبة واحدة تُسلَّم إلى الوكيل داخل صندوق الاختبار. يؤدي إيقاف صندوق الاختبار إلى تحرير الذاكرة مع الاحتفاظ بالملفات. أما تدميره فيزيل الحاوية، ويمكن للتطبيق تشغيل صندوق اختبار جديد.
ما الفرق بين sandboxd وDify وOpenHands؟
يحدث الخلط بين هذه الأدوات الثلاث لأنّها جميعاً تشغّل نموذج لغة كبيراً (LLM) على خادمك، لكنّها تنتج أشياء مختلفة. تبني Dify تطبيقات تعتمد على نماذج LLM: واجهات محادثة، وخطوط معالجة للاسترجاع، وسير عمل يستدعي نموذجاً في كل مرة يستخدمه أحد. يكون النموذج جزءاً من المنتج النهائي. يعمل OpenHands على مستودع لديك مسبقاً: تشير إليه إلى شيفرتك، فيقرأ الملفات، وينفّذ الأوامر، ويقترح التغييرات. يبدأ sandboxd من لا شيء. فهو ينشئ هيكل مشروع انطلاقاً من إعداد مسبق، ويبنيه داخل حاوية جديدة، ويمنحك URL لعرضه. والناتج تطبيق React أو FastAPI عادي لا يحتاج إلى نموذج لتشغيله.
لذلك اختر الأداة وفقاً لما تريد الحصول عليه في النهاية. يناسب sandboxd البدء من جملة والاحتفاظ بالشيفرة بعد ذلك. أما الأداتان الأخريان فتناسبان الحالات التي يكون فيها المستودع أو المنتج المعتمد على نموذج موجوداً مسبقاً.
والفرق الآخر هو عمر المشروع، وهو العامل الذي ينبغي موازنته قبل بناء أي شيء فعلي اعتماداً عليه.
البيانات وراء هذا الرسم البياني
[
{
"tool": "sandboxd",
"github_stars": "875",
"forks": "50"
},
{
"tool": "OpenHands",
"github_stars": "83,091",
"forks": "10,711"
},
{
"tool": "Dify",
"github_stars": "151,320",
"forks": "23,886"
}
]يمتلك sandboxd 875 نجمة، مقابل 83,091 لـOpenHands و151,320 لـDify. أُنشئ المستودع في 3 June 2026، ولذلك كان عمره شهرين في August 2026، بينما يعود OpenHands إلى March 2024 وDify إلى April 2023. صدر الإصدار v0.1.0 في 6 June 2026، والإصدار v0.3.6 في 1 August 2026. يصف المشروع نفسه بأنّه تجريبي، ويذكر أنّ إصدارات 0.x قد تكسر التوافق. اقرأ هذه الأرقام باعتبارها مؤشراً إلى مخاطر الاعتماديات، لا حكماً على الجودة: فالمشروع الذي يبلغ عمره شهرين لم تتح له سوى شهرين كي يكتشف الآخرون أخطاءه.
ما يحتاج إليه الخادم، وما يتعطل عند نقصه
يذكر المشروع أن 2 vCPU و4 GB من RAM تكفيان للبدء. وهذا صحيح بالنسبة إلى control plane ومساحة sandbox صغيرة واحدة، لكنه لا يكفي لشخصين ينفذان عمليات البناء في الوقت نفسه. قسّم تقدير الذاكرة إلى مكوناته. يستهلك Traefik وGo control plane موارد قليلة. أما كل sandbox قيد التشغيل، فيحتوي على toolchain كامل لـNode أو Python، وتبلغ الذروة أثناء npm install يتبعه production build. خطط لتوفير 8 GB لخادم سيبقي عدة تطبيقات قيد التشغيل، وتعامل مع swap كشبكة أمان لا كسعة إضافية، لأن عملية البناء التي تستخدم swap تستغرق دقائق بدلاً من ثوانٍ.
عند نفاد الذاكرة، تحدث مشكلتان مختلفتان ولا تبدوان متشابهتين. داخل sandbox، تصل الحاوية إلى حد --memory الصارم الذي يحدده sandboxd، فينهي kernel العملية الأكبر، ويفشل البناء من دون رسالة مفيدة من agent. يعرض docker ps -a exit code 137 لهذه الحاوية، ويعرض docker inspect عليها "OOMKilled": true. غالباً ما يطبع بناء Node الذي يفشل بهذه الطريقة JavaScript heap out of memory أولاً.
تحدث المشكلة الثانية على الخادم المضيف. يشغّل sandboxd أداة pressure reaper توقف مساحات sandbox عندما تنخفض ذاكرة المضيف، ولذلك قد تختفي sandbox على خادم صغير أثناء مشاهدة preview الخاص بها. تكون الملفات آمنة، ويوقظها الطلب التالي إلى preview URL، لكن المهمة التي كانت قيد التشغيل عند توقف الحاوية لا تُستأنف.
القرص هو المشكلة الأقل وضوحاً. يحتفظ كل تطبيق بمساحة عمل خاصة به على المضيف، ويحتوي مشروع JavaScript على شجرة node_modules قد يبلغ حجمها مئات الميغابايت. وتستهلك 10 تطبيقات عدة غيغابايت من التبعيات قبل احتساب أحجام images. ابدأ بسعة 40 GB وراقبها:
docker system df
sudo du -sh /var/lib/sandboxed/workspacesفي v0.3.6، وهو الإصدار الذي يثبته هذا الدليل، يكون دليل البيانات الافتراضي هو /var/lib/sandboxed، ويُكتب مع e الإضافي. سيؤدي إدخال /var/lib/sandboxd هناك إلى عدم العثور على شيء وإضاعة خمس دقائق في تتبع سبب مربك. تغيّر ذلك في v0.3.9 (25 August 2026). يضع المثبتون الأحدث التثبيتات الجديدة في /var/lib/sandboxd، ويحتفظون بـ/var/lib/sandboxed فقط للتثبيت الموجود مسبقاً في ذلك المسار. إذا أعددت خادماً للمرة الأولى باستخدام إصدار أحدث، فاستخدم المسار الذي لا يحتوي على e في كل أمر أدناه.
تثبيت إصدار محدد من sandboxd
يجب تثبيت Docker Engine مع إضافة Compose، بالإضافة إلى git، على الخادم أولاً. يشرح تثبيت Docker على VPS هذا الجانب.
docker compose version
git --versionيجب أن يعرض كلا الأمرين رقم إصدار. تعني docker: 'compose' is not a docker command أن إضافة Compose v2 غير مثبتة. يفضّل المثبّت الإضافة، لكنه يستخدم ملف docker-compose المستقل إذا كان مثبتاً. ويتوقف مع Docker Compose not found فقط عند عدم توفر أيٍّ منهما. تستخدم أوامر هذا الدليل docker compose، لذلك يكون تثبيت الإضافة هو الحل الأبسط.
المثبّت عبارة عن shell script يجلبه عبر الشبكة. اقرأه قبل تشغيله، وثبّت الإصدار المطلوب.
curl -fsSL https://raw.githubusercontent.com/tastyeffectco/sandboxd/v0.3.6/install.sh -o install-sandboxd.sh
less install-sandboxd.sh
SANDBOXD_REF=v0.3.6 bash install-sandboxd.shتمثل SANDBOXD_REF مرجع git الذي يسحبه المثبّت إلى $HOME/.sandboxd/src، وتكون قيمتها الافتراضية main. يعني تركها دون ضبط أن التثبيت سيستخدم ما دُمج في ذلك الصباح، وهذا مهم في مشروع أصدر ستة إصدارات في يوليو 2026 وحده. ثبّت الإصدار، ثم رقّه عمداً بعد قراءة changelog. في 12 أكتوبر 2026، كان أحدث إصدار هو v0.3.22، أي بعد الإصدار v0.3.6 المثبّت هنا بستة عشر إصداراً.
ينسخ script المصدر، ويبني images، ويشغّل stack باستخدام docker compose up -d، ثم يعرض عنوان URL لوحدة التحكم وAPI token في النهاية. احفظ هذا token في مكان آمن. فهو بيانات اعتماد لـAPI يشغّل Docker بصلاحيات root.
curl http://127.0.0.1:9090/healthzيعرض ذلك ok عندما تكون control plane قيد التشغيل. إذا لم يعرض شيئاً، فهذا يعني أن stack لم يبدأ. شغّل docker compose ps من ~/.sandboxd/src لمعرفة الخدمة المتوقفة، ثم docker compose logs sandboxd لمعرفة السبب.
الوصول إلى وحدة التحكم على خادم بعيد
تُقدَّم وحدة التحكم عبر Traefik على HTTP_PORT، وهو المنفذ 80 افتراضياً، وعلى اسم المضيف http://console.localhost. يوجّه Traefik الطلبات وفق اسم المضيف، لذلك لا يطابق إدخال عنوان IP الخاص بالخادم في المتصفح أي قاعدة، ويعيد الخطأ 404. إلى أن تضبط نطاقاً فعلياً، أنشئ إعادة توجيه للمنفذ واحتفظ باسم المضيف:
ssh -L 8080:127.0.0.1:80 you@your-vpsثم افتح http://console.localhost:8080 على حاسوبك المحمول. في Linux وmacOS، يُحل أي اسم ينتهي بـ .localhost إلى 127.0.0.1، لذلك يمر الطلب عبر النفق مع رأس Host الصحيح. اضبط كلمة مرور وحدة التحكم عند الزيارة الأولى.
امنح الوكيل نموذجاً
يتضمن الإصدار الأساسي صورتين لوكيلي برمجة: OpenCode وClaude Code. يحدد SANDBOXD_DEFAULT_AGENT أيّهما ينفّذ المهمة التي لا تحدد أحدهما، ويستخدم opencode افتراضياً. عند عدم توصيل أي مفتاح، تُنفَّذ المهام باستخدام النماذج المجانية التي لا تتطلب مفتاحاً في OpenCode Zen، لذلك لا تكلّف عملية البناء الأولى شيئاً، ويمكنك اختبار الدورة كاملة قبل إنفاق أي مبلغ.
اربط مفتاحك الخاص عندما تريد استخدام نموذج أقوى. تُرسل المفاتيح إلى مستوى التحكم، ولا تدخل إلى البيئة المعزولة مطلقاً. تُخزَّن مشفّرة ضمن دليل البيانات، ويحقنها وكيل بيانات الاعتماد أثناء الاتصال. لذلك لا يستطيع الوكيل ولا الشيفرة التي يكتبها قراءة المفاتيح.
export API=http://127.0.0.1:9090
export SANDBOXD_TOKEN=sk_... # printed by the installer
export AUTH="Authorization: Bearer $SANDBOXD_TOKEN"
curl -s -XPOST $API/v1/agents/claude-code/api-key -H "$AUTH" \
-H 'content-type: application/json' \
-d '{"api_key":"sk-ant-..."}'تنفّذ وحدة التحكم الإجراء نفسه ضمن Settings ثم AI Agents، وتتضمن تدفق OAuth إرشادياً إذا أردت استخدام اشتراك Claude بدلاً من مفتاح API. يوجد النموذج الافتراضي لكل وكيل في اللوحة نفسها، ويمكن لمهمة واحدة تجاوز هذا الإعداد.
إنشاء تطبيق صغير من البداية إلى النهاية
أنشئ التطبيق، وشغّل بيئة الاختبار المعزولة، ثم أرسل مطالبة. تعود المعرّفات بصيغة JSON، وتستخرجها عملية البدء السريع باستخدام sed، لذلك لا تحتاج إلى تثبيت jq.
APP=$(curl -s -XPOST $API/v1/apps -H "$AUTH" \
-H 'content-type: application/json' \
-d '{"name":"todo","runtime_preset":"react-vite"}' \
| sed -E 's/.*"id":"([^"]+)".*/\1/')
SB=$(curl -s -XPOST $API/v1/apps/$APP/sandbox -H "$AUTH" \
-H 'content-type: application/json' -d '{"ports":[3000]}' \
| sed -E 's/.*"id":"([^"]+)".*/\1/')
echo "app=$APP sandbox=$SB"يجب أن يحتوي المتغيران على معرّف. تعني قيمة $SB الفارغة أن بيئة الاختبار المعزولة لم تبدأ قط. والسبب المعتاد هو أن الصورة الأساسية ما زالت قيد الإنشاء أو أن ذاكرة المضيف غير كافية. وتعني قيمة 401 بدلاً من المعرّف أن bearer token غير صحيح.
curl -s -XPOST $API/v1/sandboxes/$SB/tasks -H "$AUTH" \
-H 'content-type: application/json' \
-d '{"prompt":"Add a todo list with a text input, an add button, and a delete button on each row. Keep the list in localStorage.","agent":"opencode"}'يحمل الرد معرّف مهمة. يعرض GET /v1/sandboxes/$SB/tasks/<task id> النتيجة، بينما يكون المسار /events ضمن المهمة نفسها تدفق SSE (أحداث يرسلها الخادم) مباشراً لما ينفذه العامل. وتعرض وحدة التحكم التدفق نفسه على هيئة محادثة.
يصبح التطبيق متاحاً على http://s-<sandbox id>-3000.preview.localhost، حيث يمثّل 3000 المنفذ الذي طلبته. إذا كانت بيئة الاختبار المعزولة متوقفة مؤقتاً، يصل الطلب الأول إلى المعالج العام في Traefik، ثم يبدأ sandboxd الحاوية وينتظر استجابة المنفذ، ويعرض صفحة قصيرة تفيد ببدء التشغيل وتُحدّث نفسها لعرض تطبيقك. إذا بقيت المعاينة على هذه الصفحة، فهذا يعني أن العملية داخل الحاوية لا تستمع على المنفذ المعرّف في sandbox.yaml الخاص بالتطبيق.
ضع المعاينات على نطاق حقيقي مع HTTPS
تحصل كل بيئة sandbox على اسم مضيف خاص بها، لذلك يكفي سجل DNS عام واحد لتغطيتها كلها. وجّه *.preview.yourdomain.com إلى عنوان IP للخادم باستخدام سجل A. ثم اضبط متغيرات المعاينة في .env داخل ~/.sandboxd/src:
PREVIEW_DOMAIN=yourdomain.com
PREVIEW_ENTRYPOINT=websecure
PREVIEW_TLS=true
SANDBOXD_API_AUTH_DISABLED=falseيحتاج Traefik إلى إعداد الجزء المطابق: فعّل نقطة الدخول websecure في traefik/traefik.yml، وأضف محلّل شهادات. استخدم تحدي DNS-01، لأن شهادة wildcard واحدة تغطي كل أسماء مضيفي المعاينات. أما مع HTTP-01، فستحتاج كل بيئة sandbox جديدة إلى إصدار شهادة مستقلة، وقد تؤدي فترة بناء مزدحمة إلى الوصول مباشرة إلى حدود معدل Let's Encrypt. يشرح شهادات wildcard عبر تحدي DNS-01 جانب DNS من ذلك.
cd ~/.sandboxd/src
docker compose up -dستصبح عناوين URL للمعاينات بالشكل https://s-<id>-3000.preview.yourdomain.com. افتح المنفذين 80 و443 في جدار الحماية، واترك المنفذ 9090 مغلقاً أمام الإنترنت: راجع قواعد جدار الحماية الأساسية في ufw. تذكّر أن أي شخص يستطيع تخمين اسم مضيف للمعاينة يمكنه تحميل التطبيق، لذلك تعامل مع المعاينات على أنها عامة.
إذا كنت تفضّل تجاوز النطاق وDNS والشهادات بالكامل، يوفّر المشرفون الآن sandboxd Cloud باشتراك مدفوع. يمنح خادمك عنوان HTTPS عاماً ضمن sandboxd.io مقابل 9.99 دولاراً لكل خادم شهرياً، أو 4.99 مع خصم الإطلاق، اعتباراً من October 2026. تحقّق من الإصدار المطلوب قبل الاعتماد عليه، مع تثبيت الإصدار v0.3.6.
أين تُحفظ الشفرة المُنشأة، وهل يمكنك تصديرها؟
على المضيف، داخل دليل البيانات. كل مساحة عمل عبارة عن دليل عادي في /var/lib/sandboxed/workspaces/<id>/ عند تثبيت v0.3.6، ويُربط هذا الدليل داخل الحاوية، بينما توجد ملفات التطبيق في /home/sandbox/workspace/app داخل البيئة المعزولة. حالة طبقة التحكم موجودة في ملف SQLite واحد في state/sandboxd.db، وبيانات اعتماد الوكيل المشفّرة موجودة في agent-auth/. لا يوجد شيء مخفي داخل طبقة الحاوية، لذلك تتكوّن النسخة الاحتياطية من نسخ الدليل وملف قاعدة البيانات. يتولى النسخ الاحتياطي باستخدام restic على VPS الأمرين.
sudo ls /var/lib/sandboxed/workspaces
sudo du -sh /var/lib/sandboxed/workspaces/*تصدير Git مدمج في التطبيق، وليس إضافة منفصلة. تتيح API قراءة الحالة والفروقات، ثم تنفيذ commit وpush:
curl -s $API/v1/apps/$APP/git/status -H "$AUTH"
curl -s -XPOST $API/v1/apps/$APP/git/commit -H "$AUTH" \
-H 'content-type: application/json' \
-d '{"message":"todo list, first pass"}'
curl -s -XPOST $API/v1/apps/$APP/git/push -H "$AUTH" \
-H 'content-type: application/json' -d '{"branch":"todo-first-pass"}'يذهب push دائماً إلى فرع جديد. اترك branch من دون تحديد، وستكون القيمة الافتراضية sandboxd/<slug>-<shortsha>. يُرفض كل من main وmaster والفرع الذي استوردت منه، لذلك نفّذ الدمج على الجانب البعيد.
يتطلب المستودع البعيد الخاص personal access token. عيّنه مرة واحدة في وحدة التحكم ضمن Settings، Git credentials. يُخزَّن هذا الرمز مشفّراً ويبقى خارج البيئة المعزولة، لذلك لا يستطيع الوكيل قراءته أو استخدامه لتنفيذ push من دون علمك. نفّذ push مبكراً وبانتظام. إلى أن تفعل ذلك، يظل دليل مساحة العمل النسخة الوحيدة من الشفرة، ويزيل DELETE /v1/apps/<id> هذا الدليل من دون إمكانية التراجع.
ما تكلفة عملية البناء بوحدات النموذج؟
لا يقيس sandboxd إنفاقك، لذلك يجب الرجوع إلى الرقم الظاهر في لوحة تحكم مزوّد الخدمة. نماذج OpenCode Zen المجانية لا تكلّف شيئاً، لكنها أبطأ وأضعف من النموذج المدفوع. يظهر ذلك في زيادة جولات التصحيح عند العمل على أي شيء يتجاوز تطبيقاً تجريبياً بسيطاً.
تتبع الفاتورة طريقة عمل حلقة الوكيل. يعيد كل دور إرسال السياق الذي يحتاج إليه. لذلك ترتبط التكلفة بعدد الأدوار، لا بعدد التطبيقات. يكون الطلب الواحد الذي ينجح من المحاولة الأولى منخفض التكلفة. أما تنفيذ 15 جولة من طلبات مثل «أصلح تباعد العناصر الآن» على مشروع يضم 50 ملفاً، فليس منخفض التكلفة، لأن محتويات الملفات تُرسل في كل مرة. تُسعَّر وحدات الإدخال والإخراج بشكل مختلف، ويوضح ما تكلفة وكيل البرمجة لكل جلسة النطاق الواقعي للتكلفة. ضع حداً صارماً للإنفاق لدى مزوّد الخدمة قبل أن تترك حلقة تعمل دون إشراف وبصلاحية الوصول إلى النظام.
تنظيف بيئات الاختبار القديمة
يوقف نظام التخلص من البيئات الخاملة أي بيئة اختبار ظلت خاملة لأكثر من SANDBOXD_IDLE_THRESHOLD_SECONDS، وتكون القيمة الافتراضية 2100 ثانية، أي 35 دقيقة. يحرر ذلك ذاكرة RAM مع الاحتفاظ بالملفات، ويوقظ الطلب التالي إلى عنوان URL للمعاينة الحاوية. خفّض هذه المدة على الخوادم الصغيرة، لأن بقاء الحاويات خاملة لمدة 35 دقيقة يعني حجز الذاكرة التي لا يمكنك استخدامها طوال هذه المدة.
الإيقاف لا يعني الحذف، وهنا تمتلئ الأقراص بهدوء. تظل بيئة الاختبار المتوقفة مالكة لمساحة عملها وحاويتها. إزالة بيئة الاختبار مع الاحتفاظ بالتطبيق تنفذ DELETE على بيئة الاختبار، ما يؤدي إلى حذف الحاوية ومساحة العمل معها. أما إزالة التطبيق فتحذف كل شيء نهائياً.
curl -s -XPOST $API/v1/sandboxes/$SB/stop -H "$AUTH" # frees RAM, keeps files
curl -s -XDELETE $API/v1/sandboxes/$SB -H "$AUTH" # container and workspace gone
curl -s -XDELETE $API/v1/apps/$APP -H "$AUTH" # app and everything under itبعد بضعة أسابيع من التجارب، سيعرض docker system df مساحة أكبر مما تتوقع من صور النظام القابلة للاستصلاح، لأن كل تطبيق جلب toolchain الخاص به خلّف طبقات. يحذف docker image prune الطبقات غير المرتبطة. تحقّق من GET /v1/apps أولاً، لأن الصورة التي لا تزال بيئة اختبار خاملة تشير إليها لا تُعد مهملات.
ما الذي يوفّره حدّ الحاوية وما لا يوفّره
تعمل كل بيئة معزولة بمستخدم غير مميّز، ونظام ملفات root للقراءة فقط، مع إسقاط جميع إمكانات Linux، وضبط no-new-privileges، وفرض حد أقصى للذاكرة وحد لعدد العمليات. يوضّح المشروع حدود ذلك بوضوح: حاوية Linux ذات kernel مشترك توفّر عزلاً قوياً وحداً أمنياً ضعيفاً. ويؤدي وجود خلل في kernel إلى اختراق المضيف.
تستدعي حقيقتان اتخاذ إجراء. الاتصالات الصادرة من البيئة المعزولة إلى الشبكة مفتوحة في الإصدار المستضاف ذاتياً، لذلك يمكن للشفرة المُنشأة الوصول إلى الإنترنت وشبكتك المحلية ونقاط نهاية بيانات التعريف السحابية. يوجد نظام فرعي للاتصالات الصادرة باستخدام nftables في المصدر، لكنه معطّل عند التجميع في إصدار Docker Compose المحمول، ما يعني أن القيود يجب أن يفرضها جدار الحماية على المضيف. كما أن API الخاص بطبقة التحكم يملك عملياً صلاحيات root على المضيف، لأنه يتحكم في Docker socket. وهو يستمع على 127.0.0.1:9090 افتراضياً، ويجب أن يبقى SANDBOXD_API_AUTH_DISABLED مضبوطاً على false، ولا يجوز أبداً نشره على الإنترنت.
إذا كنت تخطط للسماح لأشخاص آخرين بإرسال prompts إلى جهازك، فهذا النموذج ضعيف أكثر من اللازم بمفرده. يشير المشروع إلى gVisor مع SANDBOXD_RUNTIME=runsc، إذ يضع kernel يعمل في مساحة المستخدم بين البيئة المعزولة والمضيف. ووفقاً لقياسات المشروع نفسه، يجعل ذلك تثبيت الحزم أبطأ بنحو 1.7 مرة، والأعمال الكثيفة باستخدام system calls أبطأ بنحو 4 مرات. الحل الأقوى هو تخصيص جهاز واحد لكل مستأجر، وهو نفس مبرر تشغيل coding agents في VM مؤقتة.
هل يجدر بك البناء على مشروع عمره شهران؟
بالنسبة إلى بيئة بناء شخصية، نعم، مع اتخاذ الاحتياطات الواضحة: ثبّت SANDBOXD_REF، وانسخ دليل البيانات احتياطياً (/var/lib/sandboxed في v0.3.6، و/var/lib/sandboxd عند إجراء تثبيت جديد لـ v0.3.9 أو إصدار أحدث)، وادفع كل تطبيق تهتم به إلى مستودع git بعيد. أما أي شيء سيتعامل معه عميل، فانتظر حتى الإصدار 1.0 أو خصّص ميزانية لمعالجة الأعطال، لأن القائمين على الصيانة يوضحون صراحةً أن 0.x قد يتغير دون إشعارك. كما يبيع القائمون على الصيانة تثبيتاً مُداراً، بسعر 199 دولاراً للإعداد و79 دولاراً شهرياً للتشغيل اعتباراً من أكتوبر 2026. من المفيد معرفة ذلك عند تقييم ما إذا كان للمشروع سبب للاستمرار.
السبب في أن المخاطر مقبولة هو الناتج. ينشئ sandboxd تطبيقاً عادياً داخل مستودع git عادي. لذلك، إذا تعثر المشروع، تحتفظ بالشفرة ولا تخسر سوى الغلاف. هذا أفضل بكثير من منشئ مستضاف يملك مشروعك. وللاطلاع على الصورة الأوسع لما يستحق وضعه على خادمك هذا العام، راجع ما يستحق الاستضافة الذاتية في 2026.
FAQ
ما مواصفات الخادم الدنيا المطلوبة لـ sandboxd؟
يذكر المشروع أن 2 vCPU و4 GB من RAM تكفي للبدء، ويشمل ذلك طبقة التحكم وTraefik وsandbox واحداً صغيراً. استخدم 8 GB و40 GB من مساحة القرص إذا أردت تشغيل عدة تطبيقات في الوقت نفسه، لأن كل sandbox قيد التشغيل يحتفظ بسلسلة أدوات Node أو Python كاملة، ويحتفظ كل workspace بشجرة تبعياته الخاصة على القرص. عندما تنخفض الموارد المتاحة على المضيف، يوقف pressure reaper في sandboxd بيئات sandbox لتحرير الذاكرة. وإذا تجاوزت عملية build حد الذاكرة المخصص لـcontainer، يوقفها kernel: يعرض docker ps -a رمز الخروج 137 لهذه العملية.
كيف يختلف sandboxd عن Dify أو OpenHands؟
ينتج كل منها مخرجات مختلفة. ينشئ Dify تطبيقات تستدعي model وقت التشغيل، مثل واجهات الدردشة ومسارات الاسترجاع. يحرر OpenHands مستودعاً لديك مسبقاً، ويشغّل الأوامر ويقترح تغييرات على code موجود. ينشئ sandboxd هيكل مشروع جديد تماماً من prompt، ويبنيه داخل container الخاص به، ويعرضه على preview URL. والنتيجة تطبيق ويب عادي لا يحتاج إلى model لكي يعمل.
أين يوجد code الذي يكتبه agent فعلياً؟
يوجد على نظام ملفات المضيف، وليس داخل container image. يحصل كل تطبيق على directory في /var/lib/sandboxed/workspaces/<id>/ عند تثبيت v0.3.6، وفي /var/lib/sandboxd/workspaces/<id>/ عند تثبيت v0.3.9 أو إصدار أحدث لأول مرة. ويُركّب هذا directory كـbind mount داخل sandbox الخاص بالتطبيق، وتظهر الملفات في /home/sandbox/workspace/app داخله. تكون حالة control plane في ملف SQLite واحد ضمن state/ في data directory نفسه. يمكنك تنفيذ commit وpush إلى branch جديد على git remote من علامة Git في console، أو عبر نقطتي النهاية /v1/apps/<id>/git/commit و/git/push. ويخزّن control plane token الخاص بـprivate remotes بصورة مشفّرة، بدلاً من تمريره إلى sandbox.
هل من الآمن إتاحة sandboxd عبر الإنترنت؟
أتِح preview URLs وconsole، ولا تُتح control plane API. تتحكم API في Docker على المضيف، ولذلك تعادل root، وهي تستمع إلى 127.0.0.1:9090 افتراضياً لهذا السبب. كما تسمح sandboxes بالاتصالات الصادرة إلى الشبكة دون قيود في الإصدار المستضاف ذاتياً، ما يعني أن code الذي يكتبه agent يمكنه الوصول إلى شبكتك المحلية وإلى endpoints الخاصة ببيانات cloud الوصفية. لذلك أضف قواعد إلى host firewall إذا كان للخادم أنظمة مجاورة ينبغي حمايتها. بالنسبة إلى prompts الواردة من أشخاص لا تثق بهم، شغّل مضيفاً واحداً لكل tenant بدلاً من الاعتماد على العزل الذي يوفّره container.