איך להתקין OpenHands על VPS ב-Docker
מדריך להקמת OpenHands על שרת VPS עם Docker. למדנו איך לאבטח את ה-Docker socket כדי למנוע גישת root לא רצויה ולהגן על מערכת הקבצים שלכם.
מהו OpenHands, ומהו הסיכון היחיד שחשוב להבין תחילה
OpenHands, לשעבר OpenDevin, הוא סוכן אוטונומי להנדسة תוכנה. אתם נותנים לו משימה בשפה חופשית, והוא מתכנן את העבודה, כותב קוד, מריץ פקודות, קורא את הפלט, וחוזר על התהליך עד לסיום המשימה. ניתן להריץ אותו על שרת פרטי באמצעות Docker ולחבר אותו למודל שפה. בשרת VPS, הוא הופך לסוכן תכנות שעובד בזמן שאתם לא נמצאים.
עובדה אחת צריכה להשפיע על כל הגדרת המערכת שלכם. OpenHands לא רק מציע קוד, הוא מריץ אותו. כדי לעשות זאת, קונטיינר ה-controller שלו מחבר (mounts) את ה-Docker socket של המארח ב-/var/run/docker.sock, כדי שיוכל ליצור קונטיינרים בתוך Sandbox עבור כל משימה. כל תהליך שיכול לתקשר עם ה-Docker socket יכול להפעיל קונטיינר חדש שמחבר את כל מערכת הקבצים של המארח שלכם. המשמעות היא שגישה ל-socket היא בפועל גישת root במכונה. לכן, התייחסו למכונה שמריצה את OpenHands כשרת שמריץ קוד לא מהימן. כל בחירת אבטחה (hardening) להלן נובעת מכך.
מה נדרש
אתם זקוקים ל-VPS המריץ Ubuntu 24.04 עם Docker Engine עדכני, לפחות 4 GB של RAM, ומפתח API עבור מודל שפה (OpenAI, Anthropic, או Google), או מודל מקומי המוגש באמצעות Ollama על אותו ה-VPS. OpenHands תומך בעשרות מנועי מודלים, כך שהבחירה היא שלכם. אם מעולם לא הגדרתם קונטיינרים, היסודות של Docker ב-VPS מספקים את הרקע הנדרש למדריך זה.
התקנה באמצעות Docker
OpenHands מגיע בשתי תמונות (images): תמונת האפליקציה להרצה, ותמונת agent-server שהיא מושכת כדי להריץ את ה-sandbox של כל משימה. הריצו אותה כך, תוך החלפת ה-tags הנוכחיים מהתיעוד של הפרויקט:
docker run -it --rm --pull=always \
-e AGENT_SERVER_IMAGE_REPOSITORY=ghcr.io/openhands/agent-server \
-e AGENT_SERVER_IMAGE_TAG=1.26.0-python \
-e LOG_ALL_EVENTS=true \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.openhands:/.openhands \
-p 127.0.0.1:3000:3000 \
--add-host host.docker.internal:host-gateway \
--name openhands \
docker.openhands.dev/openhands/openhands:1.8שני פרטים יחסכו לכם שעה של בלבול. תמונת האפליקציה ותמונת ה-agent-server נושאות מספרי גרסה שונים בכוונה, לכן אל תנסו לגרום להם להיות זהים: השתמשו ב-tag של ה-agent-server שמתאים לגרסת האפליקציה לפי התיעוד. ושימו לב ל--p 127.0.0.1:3000:3000 במקום -p 3000:3000. השינוי הזה הוא ההבדל בין ממשק Web UI שרק אתם יכולים לגשת אליו, לבין ממשק שכל האינטרנט יכול לגשת אליו, וזה הנושא של הסעיף הבא.
שמירה על ה-Web UI מחוץ לאינטרנט הציבורי
OpenHands מגיש את הממשק שלו בפורט 3000. ממשק זה מפעיל סוכן שמריץ קוד, לכן פרסום הממשק באינטרנט מעניק לכל מי שמוצא אותו נתיב מרחוק לתהליך שמבצע פקודות. קשרו אותו ל-loopback, כפי שפקודת ההרצה לעיל עושה, וגשו אליו מהלפטופ שלכם באמצעות SSH tunnel:
ssh -L 3000:127.0.0.1:3000 you@your-vpsלאחר מכן פתחו את http://127.0.0.1:3000 במכונה שלכם. התעבורה עוברת דרך סשן ה-SSH הקיים, ושום דבר חדש לא מאזין באינטרנט הציבורי. להגדרה קבועה יותר, השתמשו ב-VPN. בכל מקרה, הציבו חומת אש (firewall) במצב "deny by default" לפני המכונה כדי ששום דבר לא ייחשף בטעות. זכרו שחומת אש המכסה רק IPv4 משאירה את אותו פורט פתוח ב-IPv6, וזהו פער חומת האש של IPv6 שגורם לכל כך הרבה אנשים לטעות.
בידוד מפתח המודל וכל אישורי ה-repo
OpenHands זקוק למפתח API עבור המודל שלו, ולעיתים קרובות לטוקן (token) כדי לשכפל (clone) ולדחוף (push) לתוך ה-repositories שלכם. שניהם יכולים להוציא כסף ולפעול בשמכם, לכן התייחסו אליהם כמו לסיסמאות. שמרו אותם בקובץ סביבה (environment file) שרק החשבון המתאים יכול לקרוא. לעולם אל תכתבו אותם בתוך פקודת ההרצה, שם הם נשמרים בהיסטוריית ה-shell ובציר התהליכים, ולעולם אל תשימו אותם בקובץ בתוך מאגר git.
הריצו אותו על מכונה שניתן להשמיד
מכיוון שה-controller חייב להחזיק את ה-Docker socket, אי אפשר לבצע Sandbox מלא ל-OpenHands מהמארח שלו. הפתרון המעשי הוא בידוד באמצעות מיקום: הריצו את OpenHands על VPS ייעודי שלא מכיל שום דבר אחר שחשוב לכם, לא על השרת שמריץ גם את בסיס הנתונים או את האתר שלכם. צרו snapshot לפני שתתחילו, ושחזרו מתוך ה-snapshot הזה במקום לסמוך על מכונה שהריצה קוד שנכתב על ידי סוכן במשך שבוע. VPS זול, חד-שימושי ומתכלה הוא הבית המתאים עבורו.
אבטחת המכונה (Hardening)
השאר הוא היגיינה סטנדרטית של שרת, והיא חשובה כאן יותר מהרגיל מכיוון שעומס העבודה מסוכן יותר מהרגיל. צרו משתמש מנהל (admin) ללא הרשאות root במקום לעבוד כ-root, בהתאם ל-הרצת שירותים כמשתמש ללא הרשאות. העבירו את ה-SSH לאימות באמצעות מפתח בלבד. לאחר מכן הריצו את רשימת הבדיקה (checklist) שלהלן ושמרו אותה במקום שבו תראו אותה שוב.
כדי להבין את המרכיבים הפועלים ולא רק להריץ אותם, ראו את בניית סוכן AI משלכם ב-VPS; עבור פלטפורמה עם פחות כתיבת קוד, self-hosting Dify היא דרך קלה יותר להתחיל.
FAQ
האם בטוח להריץ OpenHands על שרת?
זה יכול להיות בטוח, בזהירות, אך זה מסוכן יותר מאפליקציית Web רגילה מכיוון שהיא כותבת ומריצה קוד, וה-controller שלה מחזיק את ה-Docker socket של המארח, שהוא בפועל root במכונה. הריצו אותה על VPS ייעודי ומתכלה שלא מכיל שום דבר יקר אחר, שמרו את ה-Web UI ב-loopback מאחורי SSH tunnel או VPN, בודדו את המפתחות שלה, ואבטחו את המכונה. אל תריצו אותה לצד השירותים החשובים שלכם.
למה OpenHands זקוק ל-Docker socket?
OpenHands מריץ כל משימה בתוך קונטיינר sandbox חדש, והיא מבקשת מה-Docker daemon של המארח ליצור את הקונטיינרים הללו על ידי חיבור (mounting) של /var/run/docker.sock לתוך ה-controller שלה. זה נותן לקונטיינר ה-controller שליטה על ה-Docker במארח, דבר חזק ומסוכן, ולכן יש להתייחס למארח עצמו ככזה שמריץ קוד לא מהימן.
האם OpenHands יכולה להשתמש במודל מקומי במקום ב-API בתשלום?
כן. OpenHands תומכת במודלים מקומיים המוגשים על ידי Ollama או vLLM, כך שניתן להריץ אותה באופן עצמאי לחלוטין ללא עלות לכל טוקן וללא יציאת נתונים מהשרת שלכם. אתם זקוקים למכונה עם מספיק זיכרון עבור מודל תכנות חזק, שזהו אותו נושא של גודל זיכרון המפורט במדריך Ollama.
האם כדאי להריץ OpenHands על השרת הראשי שלי?
לא. מכיוון שהיא מריצה קוד שנכתב על ידי סוכן ומחזיקה את ה-Docker socket, שמרו אותה על VPS נפרד וחד-שימושי שאתם מוכנים לשחזר. הצבתה לצד בסיס נתונים, אתר אינטרנט או שירותים אחרים פירושה שטעות של הסוכן, או באג בו, יכולים להגיע לדברים שהם מעולם לא היו אמורים לגעת בהם.