מה המשמעות של http://127.0.0.1:3080 ב-DeepSeek Harness?
הכתובת http://127.0.0.1:3080 מופיעה כי הממשק מאזין ל-localhost בלבד מטעמי אבטחה. למדו כיצד לגשת ל-Web UI מרחוק באמצעות SSH tunnel ומדוע חשיפת הפורט מסוכנת.
מה המשמעות של dsh web: http://127.0.0.1:3080
כאשר מפעילים את פרופיל ה-web של DeepSeek Harness על גבי VPS, הוא מדפיס שורה כזו וממתין:
dsh web: http://127.0.0.1:3080/?token=...127.0.0.1 היא כתובת ה-loopback. זו הכתובת שבה מכונה משתמשת כדי לתקשר עם עצמה. socket שקשור ל-127.0.0.1 מקבל חיבורים מתהליכים שנמצאים על אותה מכונה בלבד, ולא משום מקום אחר. לכן, השורה הזו מוסרת לכם שני דברים בו-זמנית: היכן ממשק ה-Web מאזין, ומי מורשה להגיע אליו. רק המכונה שעליה רץ dsh. החלק ?token= בסוף הוא פרט אימות אקראי וחדש שהתהליך מייצר בכל פעם שהוא עולה. פירוט נוסף בהמשך.
זו הסיבה שה-URL לא מגיב כשמדביקים אותו בדפדפן במחשב הנייד שלכם. ה-127.0.0.1 של המחשב הנייד שלכם הוא המחשב הנייד שלכם. ה-harness מאזין ל-127.0.0.1 של ה-VPS, שהיא מכונה אחרת עם stack של loopback שונה. שום דבר אינו תקול. עליכם להעביר את החיבור לצד השני.
ה-README הרשמי מצהיר על ברירת המחדל בבירור: "הפקודה מפעילה את ממשק ה-Web ב-http://127.0.0.1:3080 כברירת מחדל ופותחת אותו בדפדפן ברירת המחדל עבור הרצה מקומית". בחיבור SSH אין דפדפן שניתן לפתוח, לכן ה-URL נשאר לשימושכם הידני. כתובת ה-bind מגיעה מתוסף ה-webserver host, הלא הוא @deepseek-ai/dsh-host-webserver. בגרסת 0.2.0-rc.2 שבה מתמקד מדריך זה, המפתח host שלה מתועד כ-"Listen host; the two supported values are loopback and all-interfaces". ברירת המחדל היא loopback אלא אם תשנו זאת. אם פורטים הם נושא חדש עבורכם, איך פורטים עובדים בלינוקס מכסה את מודל הכתובת-פלוס-פורט שעליו כל זה מתבסס.
מדוע ממשק ה-Web UI מאזין ל-localhost בלבד
dsh הוא רכיב הרצה (agent harness), והוא התוכנית שעוטפת את המודל: הוא מנהל את הלולאה, את קריאות הכלים ואת ההרשאות שבהן הכלים הללו פועלים. לשונית הדפדפן היא משטח שליטה עבור תהליך שמריץ פקודות shell, קורא וכותב קבצים בתיקיית העבודה שבחרת, ומשתמש ב-API key של המודל שלך. כל מי שיכול לטעון את הדף הזה יכול לבצע את כל הפעולות הללו בתור המשתמש שמריץ את dsh. הרשת אינה הדרך היחידה להגיע להרשאות הללו: תוסף שאתה מתקין רץ בתוך אותו תהליך עם אותן הרשאות, וזו הסיבה ש-בדיקת תוסף dsh לפני התקנתו דורשת את אותה רמת זהירות כמו ההחלטה על אילו פורטים השרת מאזין.
לכן, פורט 3080 אינו לוח מחוונים לקריאה בלבד. טעינת הדף הזה מעניקה הרצת פקודות על השרת.
כשפותחים את ה-URL המודפס, מגיעים ישירות לרשימת הסשנים. אין מסך התחברות ואין חשבונות משתמש. מה שחוסם את הגישה לדף הוא ה-token שבסוף ה-URL: דף ה-root מחליף אותו ב-cookie סשן חתום ומבצע הפניה (redirect) לכתובת נקייה. לאחר מכן, כל קריאת RPC וזרם WebSocket שהממשק מבצע ללא cookie תקף מקבלים 401 Unauthorized. עם זאת, לא כל מה שנמצא בפורט הזה חסום. התיעוד של תוסף ה-Connection מציין שנכסים סטטיים נשארים ציבוריים, ולשרת ה-web עצמו אין אימות ברמת השרת או מדיניות origin, כך שכל תוסף שמנהל נתיב (route) אוכף את הכללים שלו. בנתיבים המוגנים הללו, תוסף ה-Connection משיב גם 403 כאשר ה-header מסוג Host אינו loopback ואינו host שנתת בו אמון מפורש. ב-loopback זוהי שכבת הגנה שנייה הגיונית מאחורי בקרת הגישה האמיתית, שהיא מערכת ההפעלה שמאפשרת רק לתהליכים מקומיים לעבור. זו אינה סיבה לחשוף את הפורט. ה-token נשמר ב-scrollback של הטרמינל שלך ובכל log שתיעד את פלט העלייה. מדריך ה-reverse proxy של הפרויקט עצמו מציין שגם בדיקת ה-Host וגם ה-URL המפורסם אינם מגנים על הפורט המאזין עצמו. תיעוד שרת ה-web מזהיר שביצוע bind לכתובת שאינה loopback "עדיין חושף נתיבים לא מוגנים ונכסים סטטיים לאותה רשת". ובגרסה 0.2.0-rc.2 לתוסף שרת ה-web אין TLS משלו. סורקים אוטומטיים סורקים פורטים לא שגרתיים ללא הפסקה, לכן התייחס לפורט 3080 חשוף כאל פורט שכבר התגלה.
אל תפתח את פורט 3080 ב-firewall שלך, ואל תגדיר את ה-hostשל שרת ה-web ל-0.0.0.0, או לכתובת ה-IP הציבורית שלך, בשרת VPS ציבורי. שילוב כזה מותיר את היכולת להריץ פקודות על השרת שלך במרחק של URL דלף אחד מכל מי שמתחבר.
הגרסאות הנוכחיות כבר דוחפות אותך לכיוון הזה: ה-flag מסוג --host של אפליקציית ה-web מסרב לבצע bind לכל הממשקים. בגרסה 0.2.0-rc.2, לעומת זאת, מפתח התצורה host של תוסף שרת ה-web עדיין מקבל 0.0.0.0, כך שעריכת תצורה עדיין יכולה לחשוף אותו. התיעוד של שרת ה-web בענף ה-default של הפרויקט מרחיק לכת עוד יותר: הוא דוחה כתובת לא מוגדרת בזמן הטעינה ומוסיף הגדרה אופציונלית בשם tls. הוא עדיין מקבל כל כתובת קונקרטית אחת של ממשק מקומי, כך שהפניית host לכתובת ה-IP הציבורית של ה-VPS שלך חושפת את הממשק באותה מידה.
אותו היגיון חל על כל סביבת הרצה של סוכן (agent runtime) שאתה מציב על שרת, וזו הסיבה ש-הרצת סוכן פיתוח בצורה מאובטחת על VPS מתחילה מאותו כלל: פורט השליטה של הסוכן נשאר פרטי, ומשהו שאתה סומך עליו מעביר אותך אליו.
כיצד אוכל לפתוח את ממשק ה-Web UI של dsh מהמחשב הנייד שלי?
קיימות שלוש דרכים אמינות, וכל אחת מהן מותירה את ה-harness קשור ל-loopback.
- מנהרת SSH. שום דבר חדש לא מאזין בממשק הציבורי, וכבר יש ברשותך את פרטי ההזדהות. זו הדרך המומלצת לשימוש.
- רשת overlay פרטית, כך שהממשק נגיש מהמכשירים שלך בלבד ובלתי נראה לכל השאר.
- Reverse proxy שמבצע TLS termination (אבטחת שכבת תעבורה) ודורש סיסמה לפני העברת כל בקשה.
ההבדל ביניהן הוא האופן שבו הדפדפן שלך מגיע ל-loopback. באף אחת מהדרכים אין צורך להעביר את ה-harness מחוץ ל-loopback.
גישה באמצעות מנהרת SSH
הריצו פקודה זו במחשב הנייד שלכם, לא ב-VPS:
ssh -N -L 3080:127.0.0.1:3080 you@your-vpsהשאירו את התהליך רץ, ולאחר מכן פתחו בדפדפן המקומי את כתובת ה-URL המלאה dsh שהודפסה, הכוללת את ה-token בתוך http://127.0.0.1:3080/?token=.... ממשק ה-Web UI ייטען, יחליף את ה-token בעוגיית session, ויסיר את ה-token משורת הכתובת. הדפדפן שלכם שולח את 127.0.0.1:3080 בתור ה-Host, שהוא כתובת ה-loopback, לכן המנהרה עוברת את בדיקת ה-Host ללא צורך בתצורה נוספת.
הארגומנט -L מכיל שלושה שדות המופרדים בנקודתיים. הראשון הוא הפורט לפתיחה במחשב הנייד שלכם. השני והשלישי הם הכתובת והפורט שאליהם תועבר כל התקשרות. הפרט החשוב: 127.0.0.1 בשדה האמצעי מפוענח על ידי שרת ה-SSH ב-VPS, לאחר שהתעבורה שלכם כבר הגיעה לשם. המשמעות היא ה-loopback של ה-VPS, לא שלכם. זו בדיוק הכתובת ש-dsh הדפיס, וזו הסיבה שהמנהרה עובדת כאשר חיבור דפדפן ישיר אינו עובד.
-N מורה ל-SSH לא להריץ פקודה מרוחקת, כך שתקבלו מעביר תעבורה ללא shell. עבור מנהרת רקע שנכשלת בקול רם במקום בשקט:
ssh -N -f -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -L 3080:127.0.0.1:3080 you@your-vps-f מעביר את התהליך לרקע לאחר אימות. ExitOnForwardFailure=yes חשוב יותר ממה שהוא נראה: בלעדיו, SSH מתחבר בהצלחה גם כאשר העברת הפורטים לא הוגדרה, כך שתקבלו session פעיל ומנהרה מתה ללא אזהרה. ServerAliveInterval=30 שולח keepalive בכל 30 שניות כדי שמנהרה לא פעילה תשרוד פסקי זמן של NAT (תרגום כתובות רשת) בנתבים של בתי קפה ומלונות.
מה עליכם לראות
ב-VPS, ודאו מה באמת מאזין:
ss -ltnp | grep 3080תוצאה תקינה מציינת את כתובת ה-loopback:
LISTEN 0 511 127.0.0.1:3080 0.0.0.0:* users:(("node",pid=1042,fd=21))אם עמודת הכתובת המקומית מציגה 0.0.0.0:3080 במקום זאת, ה-Web UI נמצא על כל ממשק, כולל הציבורי. ה-IP הציבורי של ה-VPS שלכם באותה עמודה משמעותו חשיפה זהה. עצרו את התהליך ותקנו את ה-bind לפני שתעשו כל דבר אחר. אם ss מדפיס את ה-socket אך משאיר את השדה users: ריק, הריצו אותו עם sudo, כיוון ששם התהליך עבור socket בבעלות משתמש אחר מוסתר אחרת.
כאשר המנהרה מסרבת להתחיל
SSH מדפיס זאת ויוצא:
bind [127.0.0.1]:3080: Address already in use
channel_setup_fwd_listener_tcpip: cannot listen to port: 3080הבעיה היא במחשב הנייד שלכם, לא בשרת. משהו מקומי כבר תופס את פורט 3080, לעיתים קרובות מנהרה קודמת ששכחתם. בחרו פורט מקומי פנוי במקום:
ssh -N -L 3081:127.0.0.1:3080 you@your-vpsרק השדה הראשון השתנה, לכן כעת עליכם לגלוש ל-http://127.0.0.1:3081/?token=..., עם אותו ה-token, בזמן שה-harness ממשיך להאזין ב-3080. שני המספרים לא חייבים להיות זהים. עוגיית ה-session קשורה ל-host ולפורט בשורת הכתובת, לכן פורט מקומי חדש דורש את ה-URL עם ה-token פעם נוספת.
אם המנהרה עולה אך הדפדפן מדווח על חיבור שסורב או תשובה ריקה, התעבורה עברה ל-VPS ולא מצאה דבר בצד השני. או ש-dsh יצא, או שהוא ביצע bind לפורט אחר. בדקו עם ss -ltnp | grep 3080 בשרת. אם הדף עונה ב-401 Unauthorized, המנהרה תקינה והדפדפן שלכם פשוט לא מחזיק עוגייה תקפה לכתובת זו: פתחו שוב את ה-URL המודפס, כולל ה-token. לאחר אתחול, קחו את ה-URL מהפלט החדש, כיוון שכל תהליך מייצר token חדש.
דבר נוסף שמכשיל משתמשים כאן: npx @deepseek-ai/dsh web שרץ בחזית מת כשה-shell נסגר, לכן ה-harness נעצר ברגע שאתם מתנתקים. התחילו אותו בתוך tmux או תחת service של משתמש ב-systemd, שזו אותה בעיה שנפתרה ב-שמירה על סוכן קידוד רץ ב-VPS. תחת systemd, שורת ה-dsh web:, כולל ה-token, נרשמת ביומן ה-service, לכן קראו אותה משם. בזמן שאתם עובדים על צד ה-SSH, כדאי לבצע קודם לכן הקשחת SSH ב-VPS שלכם, כיוון שהמנהרה הופכת את התחברות ה-SSH שלכם לדלת היחידה לסוכן.
גישה דרך רשת Overlay פרטית
רשת Overlay מעניקה ל-VPS ולמחשב הנייד שלכם כתובות ברשת פרטית שאליה מצטרפים רק המכשירים שלכם. Tailscale היא הבחירה הנפוצה, והפקודה serve שלה מתאימה בדיוק למקרה זה: tailscaled רץ על ה-VPS ומתחבר ל-localhost:3080 עצמו, כך שה-harness נשאר על ה-loopback.
tailscale serve --bg localhost:3080
tailscale serve statusממשק המשתמש נגיש כעת תחת שם המכשיר שלכם בתוך ה-tailnet, באמצעות HTTPS, ללא צורך בפתיחת פורט בממשק הציבורי. פעולה זו מחייבת הפעלת תעודות HTTPS עבור ה-tailnet שלכם, אחרת ל-serve אין תעודה להציג. מכיוון שהדפדפן שלכם שולח כעת את שם ה-tailnet בתור ה-Host, הפעילו את ה-harness עם השם המורשה, אחרת קריאות ה-API שלו יקבלו 403. רשומה ללא פורט תואמת לכל פורט:
npx @deepseek-ai/dsh@0.2.0-rc.2 web --trusted-host your-vps.your-tailnet.ts.netלאחר מכן פתחו את https://your-vps.your-tailnet.ts.net/?token=..., והעבירו את ה-token מהשורה שהודפסה. כדי להסיר את ההגדרה, חזרו על הפקודה עם off:
tailscale serve --https=443 offהשתמשו ב-serve, לעולם לא ב-funnel. הפקודה Funnel מפרסמת את אותו יעד לאינטרנט הציבורי, מה שחושף את ה-agent runtime בפורט פתוח ללא הגנה מלבד ה-token ב-URL. שתי הפקודות נראות כמעט זהות אך מבצעות פעולות הפוכות, לכן קראו על ההבדל בין Tailscale Serve ל-Funnel לפני שתקלידו אחת מהן. המדריך Tailscale כרשת פרטית מכסה את תהליך ההגדרה עצמו.
גישה דרך reverse proxy עם אימות סיסמה
זוהי האפשרות שחושפת פורט לאינטרנט באופן ממשי, לכן האימות הוא המחסום היחיד שחוצץ בין גורם זר לבין הרצת פקודות בשרת שלכם. בחרו באפשרות זו כאשר כמה משתמשים זקוקים לממשק המשתמש ושימוש ב־tunnel עבור כל אחד מהם אינו מעשי.
ה־harness נשאר על 127.0.0.1:3080. nginx רץ על אותו שרת, לכן הוא יכול להגיע ל־loopback, והוא מאזין בפורט 443 עם תעודה וקובץ סיסמאות.
server {
listen 443 ssl;
server_name dsh.example.com;
ssl_certificate /etc/letsencrypt/live/dsh.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dsh.example.com/privkey.pem;
auth_basic "dsh";
auth_basic_user_file /etc/nginx/dsh.htpasswd;
location / {
proxy_pass http://127.0.0.1:3080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 3600s;
proxy_buffering off;
}
}צרו את קובץ הסיסמאות ובצעו טעינה מחדש:
sudo apt install -y apache2-utils
sudo htpasswd -c /etc/nginx/dsh.htpasswd you
sudo nginx -t && sudo systemctl reload nginxהפקודה nginx -t אמורה להדפיס syntax is ok ולאחריה test is successful. טעינה מחדש עם קובץ פגום תיכשל ותשאיר את התצורה הפעילה כפי שהיא, לכן קראו את השגיאה במקום לבצע הפעלה מחדש באופן עיוור.
שלוש משורות ה־proxy הללו אינן קישוט. ה־headers Upgrade ו־Connection מאפשרים ל־WebSocket handshake לעבור; בלעדיהם הדף ייטען אך לא יתעדכן לעולם. proxy_read_timeout 3600s מחליף את ברירת המחדל של 60 שניות, שאחרת קוטעת הרצה ארוכה של סוכן באמצע התגובה וגורמת לממשק להיראות קפוא. proxy_buffering off שולח את פלט המודל לדפדפן ברגע שהוא מגיע, במקום להמתין עד לסיום התגובה. הסבר שורה אחר שורה על תצורת nginx reverse proxy מפרט את השאר, ו-בחירה בין nginx, Caddy ו־Traefik מכסה ביצוע של אותה פעולה עם תעודות אוטומטיות.
ה־harness צריך להכיר גם את ה־proxy. proxy_set_header Host $host מעביר את השם שפונה לדפדפן ללא שינוי, כפי שמבקש מדריך ה־proxy של הפרויקט, לכן התחילו את dsh כשהשם הזה מוגדר כמורשה, אחרת הוא ישיב 403:
npx @deepseek-ai/dsh@0.2.0-rc.2 web --trusted-host dsh.example.comכל אדם פותח לאחר מכן את https://dsh.example.com/?token=... פעם אחת, עם ה־token משורת ה־dsh web:, והדפדפן שומר את ה־session cookie לאחר מכן. ה־backend מגדיר את ה־cookie הזה ללא הדגל Secure, ומדריך ה־proxy מבקש מה־proxy להוסיף אותו ב־HTTPS. בגרסת nginx 1.19.3 ומעלה, proxy_cookie_flags ~ secure; בבלוק location מבצע זאת.
השאירו את 3080 סגור ב־firewall ללא קשר ל־proxy שתבחרו, כך שהנתיב היחיד פנימה יהיה דרך זה שעבר אימות. יסודות ufw firewall מכסה את הכללים. אימות בסיסי מעל TLS הוא רף מינימלי, לא מודל אבטחה מלא: מי שמחזיק בסיסמה ובכתובת ה־token מחזיק בגישת shell לשרת שלכם. העדיפו שימוש ב־tunnel כאשר הדבר מתאפשר.
איך משנים את הפורט שבו dsh web מאזין?
--port שייך ליישום ה-web, לא למפעיל (launcher). תיעוד ה-CLI מציג את הדוגמה ישירות:
dsh --profile web --port 8080dsh web הוא כינוי (alias) ל---profile web, לכן dsh web --port 8080 היא אותה פקודה. המפעיל מנתח רק את הדגלים שלו ומעביר את כל מה שאחריהם לפרופיל שהופעל. לכן, דגלי המפעיל מופיעים ראשונים, והטוקן הראשון שהמפעיל אינו מזהה מתחיל את הארגומנטים של היישום. הציבו את --port אחרי הפרופיל, לעולם לא לפניו.
קראו את ה-URL שהפקודה מדפיסה במקום להניח מהו, כיוון שהשורה הזו מדווחת על הכתובת שאליה השרת באמת נקשר, יחד עם הטוקן שתצטרכו. לאחר מכן עדכנו את השדה האחרון במנהרת ה-tunnel שלכם בהתאם:
ssh -N -L 3080:127.0.0.1:8080 you@your-vpsלשינוי קבוע, הפורט נמצא בתצורת הפרופיל במקום בשורת הפקודה. הפרופילים web ו-headless מאתחלים את עצמם אוטומטית בשימוש הראשון מתוך תבניות מוכנות, תחת ~/.dsh. אותה תיקייה היא המקום שבו נמצאות הגדרות מפתח ה-API ונקודת הקצה (endpoint) של המודל שלכם, לכן הגדרת מפתחות, מודלים ו-endpoints ב-dsh היא קריאה מומלצת אם אתם כבר עורכים קבצים אלו. כדי לראות מה באמת בתוקף לאחר שכל השכבות מתמזגות:
dsh --dump-configכתובת ההאזנה מגיעה משני מפתחות בתוסף ה-webserver, host ו-port. בגרסת 0.2.0-rc.2 שאר המפתחות שלה מכווננים רק את דחיסת התגובה, והענף (branch) המקורי מוסיף מפתח אופציונלי tls. הגדרת port ל-0 מבקשת ממערכת ההפעלה פורט פנוי, ומתועדת כ-"zero requests an OS-assigned port". זה מבטיח שלעולם לא תיתקלו בהתנגשות, אך זהו פתרון לא מתאים עבור tunnel, כיוון שהמספר משתנה בכל הפעלה מחדש.
מדוע dsh נכשל עם השגיאה address already in use?
הסיבה היא שתהליך אחר כבר תופס את הכתובת והפורט הללו, ולכן ה-kernel מסרב לבצע bind שני. Node מדווח על כך כך:
Error: listen EADDRINUSE: address already in use 127.0.0.1:3080מצאו את התהליך שמחזיק בפורט לפני שתשנו דבר מה:
sudo ss -ltnp | grep 3080השדה users:(("node",pid=1042,fd=21)) מציין את שם התהליך ואת ה-PID שלו. התשובה הנפוצה היא שמופע קודם של dsh שחשבתם שנסגר, עדיין פעיל בתוך חלון tmux מנותק. עצרו את התהליך ההוא באמצעות kill 1042, או הפעילו את המופע החדש בפורט אחר. שימו לב ש-127.0.0.1:3080 ו-0.0.0.0:3080 מתנגשים זה עם זה, כיוון שביצוע bind לכל הממשקים כבר כולל בתוכו את ה-loopback.
קבעו גרסה ספציפית, כיוון שמדובר בגרסת תצוגה למפתחים
הקובץ README מבהיר זאת ללא כחל וסרק: DeepSeek Harness נמצא בשלב תצוגה למפתחים ועובר שינויים מהירים, וצפויים בו שינויים שאינם תואמים לאחור. אם קצב זה הוא הסיבה להיסוס שלכם, השוואה בין dsh לבין Claude Code ו-Omnigent בוחנת זאת אל מול שני כלים הנמצאים בנקודות שונות על אותו עקומת פיתוח.
ציון npx @deepseek-ai/dsh web ללא גרסה אינו מגדיר גרסה, ולכן אין לכם שליטה על ה-build שיופעל. התיעוד של npm מציין כי שם חבילה ללא מציין גרסה "יותאם לכל גרסה הקיימת בפרויקט המקומי", וחבילה שחסרה בפרויקט מותקנת לתיקייה בתוך ה-cache של npm. ה-build שיופעל תלוי במה שקיים באותה מכונה במקרה, כך שאתחול עלול להפעיל CLI שונה מזה שבדקתם, עם דגלים (flags) שונים. קבעו גרסה ספציפית כדי שאתחול לא יבצע שדרוג:
npx @deepseek-ai/dsh@0.2.0-rc.2 webנכון לאוקטובר 2026 (נבדק ב-2026-10-18), התג latest של npm מצביע על 0.2.0-rc.2, שפורסמה ב-2026-09-29. התג next התקדם: הוא מצביע כעת על 0.2.1-rc.2, שפורסמה ב-2026-10-17, שעות ספורות לאחר 0.2.1-rc.1, כך ששימוש ב-npx @deepseek-ai/dsh@next ללא מציין גרסה יפעיל מועמד לשחרור (release candidate) בגרסה 0.2.1, ולא את ה-build שבו מדריך זה נוקב. תג alpha נפרד נושא את 0.2.1-alpha.5, שפורסמה ב-2026-10-16, החדשה ביותר מבין מספר גרסאות אלפא ששוחררו באותו שבוע. ה-build של 0.1.0-rc.7 שמדריך זה קבע באוגוסט נמצא כעת בפיגור של גרסאות תצוגה רבות, לאורך שאר קו 0.1 ואל תוך 0.2. בדקו מה npx ללא מציין גרסה ימשוך לפני שתאשרו זאת:
npm view @deepseek-ai/dsh versionהפקודה npm view @deepseek-ai/dsh dist-tags מציגה את כל התגים בבת אחת, וזו הדרך לזהות מועמד לשחרור לעומת גרסת אלפא לפני שקובעים את הגרסה.
אם הקיבוע מסרב להתקין, או ש-npx ממשיך להפעיל את ה-build הישן לאחר שקיבעתם גרסה חדשה, שגיאות התקנה וגרסה נפוצות מכסה את ניקוי ה-cache של npx ובדיקה איזו גרסת npm צרופה ל-Node שלכם.
דגלים עוברים בין ה-launcher לבין יישום ה-web לאורך גרסאות התצוגה. אם --port מפסיק להתנהג כפי שמתואר במדריך זה, בקשו מהיישום את רשימת הדגלים שלו במקום לנחש:
dsh --profile web --helpלגבי ההתקנה עצמה, הגדרת סביבת העבודה ומפתח המודל, ראו התקנת DeepSeek Harness על גבי VPS. למדריך מקוצר לשלב הגישה בלבד, גישה לממשק ה-Web של dsh על גבי VPS מכסה את ה-tunnel ללא ההסברים התאורטיים.
FAQ
מדוע איני יכול לפתוח את http://127.0.0.1:3080 בדפדפן במחשב הנייד שלי?
הסיבה היא ש-127.0.0.1 מייצג את המכונה שבה אתה מקליד. ממשק ה-Web של DeepSeek Harness מאוגד לכתובת ה-loopback של ה-VPS, לכן רק תהליכים שרצים על ה-VPS יכולים להתחבר אליו. למחשב הנייד שלך יש כתובת loopback נפרדת משלו, ושום דבר לא מאזין בפורט 3080 שם. בצע העברת פורט (port forwarding) דרך SSH בעזרת ssh -N -L 3080:127.0.0.1:3080 you@your-vps, ולאחר מכן טען את ה-URL המלא שהודפס, http://127.0.0.1:3080/?token=..., באופן מקומי. השדה האמצעי בארגומנט -L מתורגם בצד השרת, וזה מה שגורם לו להצביע על ה-harness. אם תשמיט את ה-token, תקבל 401 Unauthorized עד שהדפדפן שלך יחזיק ב-session cookie.
האם זה בטוח לאגד את ממשק ה-Web של dsh ל-0.0.0.0 ב-VPS ציבורי?
לא. ממשק ה-Web הוא משטח השליטה עבור סוכן שמריץ פקודות shell ועורך קבצים תחת המשתמש שמריץ את dsh. אין לו חשבונות משתמשים או מסך התחברות: האישור היחיד הוא ה-token ב-URL המודפס, נכסים סטטיים מוגשים ללא אימות, והתיעוד של הפרויקט עצמו מציין שהפורט שבו הוא מאזין אינו מוגן. איגוד לכל הממשקים בכתובת IP ציבורית חושף את הרצת הפקודות בשרת שלך לכל מי שמגיע לפורט 3080, במרחק של URL דלף אחד בלבד. איגוד ישירות לכתובת ה-IP הציבורית נושא את אותו סיכון. השאר את האיגוד על 127.0.0.1, השאר את פורט 3080 סגור ב-firewall, והשתמש ב-SSH tunnel, ברשת overlay פרטית, או ב-reverse proxy שדורש סיסמה.
כיצד אוכל להשאיר את ממשק ה-Web של dsh רץ לאחר סגירת ה-session של ה-SSH?
תהליך npx @deepseek-ai/dsh web שרץ ב-foreground הוא תהליך בן של ה-shell שבו התחברת, לכן הוא נסגר כאשר ה-shell נסגר. הפעל אותו בתוך session של tmux והתנתק בעזרת Ctrl-b d, או הרץ אותו כשירות systemd של משתמש עם lingering מופעל. ה-tunnel וה-harness הם עצמאיים: אתה יכול לנתק ולבנות מחדש את ה-SSH tunnel בתדירות שתרצה מבלי להשפיע על ה-harness שרץ, כל עוד ל-harness יש תהליך אב ששורד את ה-login שלך.
מדוע ממשק ה-Web של dsh קופא באמצע הרצה ארוכה של סוכן מאחורי nginx?
הסיבה היא שערך ה-proxy_read_timeout המוגדר כברירת מחדל ב-nginx הוא 60 שניות, לכן הוא סוגר חיבור שלא מפיק נתונים במשך דקה, דבר שקורה בקלות בשלב ארוך של סוכן. הגדר את proxy_read_timeout 3600s; בתוך בלוק ה-location. הוסף את proxy_buffering off; כדי שהפלט יוזרם לדפדפן ברגע שהוא מגיע, והעבר את ה-headers מסוג Upgrade ו-Connection עם proxy_http_version 1.1; כדי שביצוע ה-handshake של ה-WebSocket יצליח. ללא ה-headers הללו, הדף נטען אך לעולם לא מקבל עדכונים.