המדריך הזה מריץ ארגז חול מ־JavaScript או מ־TypeScript. תפעילו microVM מבודד של Firecracker, תריצו קוד בשלוש שפות, תעבירו קבצים ותעקבו אחרי הפלט של משימה ארוכה. כל שלב הוא קטע קוד קצר.
צריך Node.js 18+ (או Deno, או Bun) וחשבון EQVPS.
1. השיגו טוקן
ה־SDK מזדהה עם טוקן חשבון רגיל. איך משיגים אותו מלוח הבקרה, מה־API או משרת ה־MCP מוסבר בחיבור החשבון.
export EQVPS_API_KEY="your-token"
חשבון חדש בלי יתרה מקבל קרדיט של 1 דולר לארגזי חול כשהוא יוצר ארגז חול בפעם הראשונה. זה מספיק למדריך הזה פעמים רבות.
2. התקינו את ה־SDK
npm i @eqvps/sdk
הדוגמאות משתמשות במודולי ES וב־await ברמה העליונה. שמרו אותן כקבצי .mjs, או כ־.ts והריצו עם npx tsx.
3. הפעילו ארגז חול והריצו קוד
import { Sandbox } from "@eqvps/sdk";
await Sandbox.with({ tariff: "small" }, async (sb) => {
console.log(sb.id);
const r = await sb.run("import platform; print(platform.python_version())");
console.log(r.exit_code, r.stdout);
});
הפלט הוא מזהה ארגז החול (sb_ ועוד 24 תווים), ואחריו 0 3.12.x. Sandbox.with מוחק את ארגז החול כשהפונקציה מסתיימת, גם אם היא זורקת שגיאה.
שפת ברירת המחדל היא Python. שתי האחרות במרחק אפשרות אחת:
await Sandbox.with({}, async (sb) => {
const js = await sb.run("console.log(process.version)", { language: "node" });
const sh = await sb.run("uname -r && nproc", { language: "bash" });
console.log(js.stdout, sh.stdout);
});
סקריפט שנכשל לא זורק כלום. בדקו את r.ok, שהוא true כש־exit_code הוא 0 והפקודה לא הגיעה למגבלת הזמן.
4. פקודות shell וחבילות
exec מקבל מחרוזת shell או מערך argv. לארגז החול יש גישה לאינטרנט, כך שהתקנות דרך npm ו־pip עובדות:
await Sandbox.with({ tariff: "small" }, async (sb) => {
await sb.exec("mkdir -p /root/app && cd /root/app && npm init -y && npm i lodash", { timeout: 55 });
const r = await sb.exec(["node", "-e", "console.log(require('/root/app/node_modules/lodash').VERSION)"]);
console.log(r.stdout);
});
קריאה סינכרונית נמשכת לכל היותר 55 שניות. כל מה שארוך יותר עובר למשימת רקע (שלב 6).
5. קבצים
await Sandbox.with({}, async (sb) => {
await sb.upload("/root/input.json", JSON.stringify({ values: [3, 5, 8] }));
await sb.run("import json; d = json.load(open('/root/input.json')); open('/root/out.txt', 'w').write(str(sum(d['values'])))");
console.log(await sb.downloadText("/root/out.txt")); // 16
});
upload מקבל מחרוזת או Uint8Array. download מחזיר Uint8Array, ו־downloadText מחרוזת. העברה אחת מוגבלת ל־5 MB.
6. משימות ארוכות עם פלט חי
await Sandbox.with({ tariff: "standard" }, async (sb) => {
const task = await sb.exec("for i in 1 2 3 4 5; do echo step $i; sleep 20; done", { background: true });
const res = await task.wait({ onOutput: (out) => process.stdout.write(out) });
console.log(res.state, res.exit_code); // done 0
});
המשימה חוזרת מיד ואין לה מגבלה של 55 שניות. wait בודק כברירת מחדל כל 2 שניות (את זה משנה pollIntervalMs). task.kill() עוצר אותה, ו־sb.task(id) מתחבר אליה מחדש מתהליך אחר.
שגיאות
import { Sandbox, InsufficientBalanceError, RateLimitError } from "@eqvps/sdk";
try {
await Sandbox.with({}, async (sb) => console.log((await sb.run("print(1)")).stdout));
} catch (e) {
if (e instanceof InsufficientBalanceError) console.log("Top up the balance");
else if (e instanceof RateLimitError) console.log("Busy, retry in", e.retryAfter);
else throw e;
}
ה־SDK מנסה שוב בעצמו 429 ו־503, עד שלוש פעמים, כשהשרת שולח Retry-After. ה־429 הנפוץ ביותר נובע מהרצה של יותר משתי פקודות בבת אחת באותו חשבון. כל המחלקות מופיעות במדריך ה־SDK.
העלות של המדריך
כל דוגמה חיה כמה שניות וחויבה לפי המינימום של 60 שניות: 0.00055 דולר ב־small, 0.0011 דולר ב־standard. המשימה משלב 6 רצה כ־100 שניות ב־standard, בערך 0.002 דולר. הכול יחד הרבה פחות מסנט. רשימת המחירים המלאה במגבלות וחיוב של ארגזי חול.
השלבים הבאים
- אותו הדבר ב־Python: SDK של Python לארגזי חול ב־5 דקות.
- חברו מודל ותנו לו להריץ את הקוד שלו: משימת הסוכן הראשונה שלכם בארגז חול.
- תעריפים וניסיון ב־1 דולר: עמוד ארגזי החול.
תגובות
אין עדיין תגובות. היו הראשונים.