dsh web: http://127.0.0.1:3080 का क्या अर्थ है?
dsh द्वारा http://127.0.0.1:3080 दिखाने का कारण इसका localhost पर बाइंड होना है। इसे सुरक्षित रूप से एक्सेस करने के लिए SSH टनल का उपयोग करें और पोर्ट 3080 को सीधे ओपन न करें।
dsh web: http://127.0.0.1:3080 का अर्थ
जब आप VPS पर DeepSeek Harness वेब प्रोफाइल शुरू करते हैं, तो यह दो लाइनें प्रिंट करता है और फिर प्रतीक्षा करता है:
dsh web: http://127.0.0.1:3080
Ready.127.0.0.1 लूपबैक एड्रेस है। यह वह एड्रेस है जिसका उपयोग मशीन खुद से बात करने के लिए करती है। 127.0.0.1 पर बाइंड किया गया सॉकेट केवल उसी मशीन की प्रक्रियाओं से कनेक्शन स्वीकार करता है, और कहीं से नहीं। इसलिए वह लाइन आपको एक साथ दो बातें बताती है: वेब UI कहाँ लिसन कर रहा है, और इसे एक्सेस करने की अनुमति किसे है। केवल वह मशीन जिस पर dsh चल रहा है।
यही कारण है कि जब आप इसे अपने लैपटॉप के ब्राउज़र में पेस्ट करते हैं तो URL काम नहीं करता है। आपके लैपटॉप का 127.0.0.1 आपका लैपटॉप ही है। हार्नेस VPS के 127.0.0.1 पर लिसन कर रहा है, जो एक अलग मशीन है और जिसका लूपबैक स्टैक अलग है। कुछ भी खराब नहीं है। आपको कनेक्शन को आगे ले जाने (carry) की आवश्यकता है।
आधिकारिक README डिफ़ॉल्ट को स्पष्ट रूप से बताता है: "कमांड वेब UI शुरू करता है, जो डिफ़ॉल्ट रूप से http://127.0.0.1:3080 पर सर्व होता है।" बाइंड एड्रेस वेबसर्वर होस्ट प्लगइन, @deepseek-ai/dsh-host-webserver से आता है, जिसकी host की को "Listen host; the two supported values are loopback and all-interfaces" के रूप में प्रलेखित किया गया है। जब तक आप इसे बदलते नहीं हैं, तब तक आपको लूपबैक ही मिलता है। यदि पोर्ट्स आपके लिए नए हैं, तो Linux पर पोर्ट्स कैसे काम करते हैं उस एड्रेस-प्लस-पोर्ट मॉडल को कवर करता है जिस पर यह सब आधारित है।
Web UI केवल localhost पर bind क्यों होता है
dsh एक agent harness है। ब्राउज़र टैब एक ऐसी प्रक्रिया के लिए control surface है जो shell commands चलाती है, आपके द्वारा चुने गए workspace directory में फाइलें पढ़ती और लिखती है, और आपकी model API key का उपयोग करती है। जो कोई भी उस पेज को load कर सकता है, वह dsh चलाने वाले user के रूप में यह सब कर सकता है।
इसलिए port 3080 केवल read-only dashboard नहीं है। उस पेज को load करने का अर्थ है सर्वर पर command execution की अनुमति देना।
Web UI खोलते ही आप सीधे session list पर पहुँच जाते हैं। यहाँ कोई login prompt नहीं है, क्योंकि developer preview में कोई user accounts और remote authentication नहीं है। loopback पर यह सुसंगत है: operating system ही access control है, और केवल local processes ही इसे access कर सकती हैं। यदि आप उसी सर्वर को public IP वाले VPS पर 0.0.0.0 पर bind करते हैं, तो वही पेज पूरे इंटरनेट के लिए खुल जाता है, और इसके आगे कोई सुरक्षा नहीं होती। Automated scanners लगातार असामान्य ports को scan करते रहते हैं, इसलिए एक published 3080 को हमेशा 'खोजा गया' (found) मानकर चलें।
अपने firewall में port 3080 न खोलें, और public VPS पर webserverhostको0.0.0.0पर सेट न करें। यह संयोजन आपके सर्वर पर command execution का अधिकार उसे दे देता है जो सबसे पहले connect करता है।
यही तर्क सर्वर पर रखे गए हर agent runtime पर लागू होता है, और इसीलिए VPS पर coding agent को सुरक्षित रूप से चलाना इसी नियम से शुरू होता है: agent का control port निजी रहना चाहिए, और आप जिस पर भरोसा करते हैं, वही आपको उस तक पहुँचाना चाहिए।
मैं अपने लैपटॉप से dsh Web UI कैसे खोलूँ?
इसके तीन सही तरीके हैं, और इनमें से हर एक harness को loopback पर ही सीमित रखता है।
- एक SSH tunnel। सार्वजनिक इंटरफ़ेस पर कोई नई चीज़ listen नहीं करती है, और आपके पास पहले से ही credentials मौजूद हैं। उपयोग करने के लिए यही सबसे अच्छा तरीका है।
- एक private overlay network, ताकि UI आपके अपने उपकरणों से तो पहुँच योग्य हो, लेकिन बाकी किसी को दिखाई न दे।
- एक reverse proxy जो TLS (transport layer security) को terminate करता है और किसी भी चीज़ को forward करने से पहले पासवर्ड मांगता है।
इनके बीच का अंतर यह है कि आपके ब्राउज़र को loopback तक कौन पहुँचाता है। इनमें से किसी में भी harness को loopback से हटाना शामिल नहीं होना चाहिए।
SSH tunnel के माध्यम से पहुँचें
इसे अपने लैपटॉप पर चलाएं, VPS पर नहीं:
ssh -N -L 3080:127.0.0.1:3080 you@your-vpsइसे चलते रहने दें, फिर अपने स्थानीय ब्राउज़र में http://127.0.0.1:3080 खोलें। Web UI लोड हो जाएगा।
-L तर्क (argument) में कोलन (colons) द्वारा अलग किए गए तीन फ़ील्ड होते हैं। पहला आपके लैपटॉप पर खुलने वाला पोर्ट है। दूसरा और तीसरा वे पता और पोर्ट हैं जहाँ प्रत्येक कनेक्शन को फॉरवर्ड करना है। महत्वपूर्ण विवरण यह है: बीच के फ़ील्ड में 127.0.0.1 को VPS पर मौजूद SSH सर्वर द्वारा रिज़ॉल्व किया जाता है, जब आपका ट्रैफ़िक वहाँ पहुँच चुका होता है। इसका मतलब VPS का लूपबैक है, आपका नहीं। यही वह सटीक पता है जिसे dsh प्रिंट करता है, और इसीलिए यह टनल तब काम करती है जब सीधा ब्राउज़र कनेक्शन काम नहीं करता।
-N SSH को रिमोट कमांड न चलाने के लिए कहता है, जिससे आपको केवल एक फॉरवर्डर मिलता है और कोई शेल नहीं। ऐसी बैकग्राउंड टनल के लिए जो चुपचाप फेल होने के बजाय स्पष्ट रूप से फेल हो:
ssh -N -f -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -L 3080:127.0.0.1:3080 you@your-vps-f प्रमाणीकरण (authentication) के बाद इसे बैकग्राउंड में डाल देता है। ExitOnForwardFailure=yes जितना दिखता है उससे कहीं अधिक महत्वपूर्ण है: इसके बिना, SSH तब भी सफलतापूर्वक कनेक्ट हो जाता है जब फॉरवर्ड सेटअप नहीं हो पाता, जिससे आपको एक काम करने वाला सेशन तो मिलता है लेकिन टनल मृत होती है और कोई चेतावनी नहीं मिलती। ServerAliveInterval=30 हर 30 सेकंड में एक कीप-अलाइव (keepalive) भेजता है ताकि एक निष्क्रिय टनल कैफे और होटल राउटर के NAT (नेटवर्क एड्रेस ट्रांसलेशन) टाइमआउट के दौरान भी बनी रहे।
आपको क्या देखना चाहिए
VPS पर, पुष्टि करें कि वास्तव में क्या लिसन (listen) कर रहा है:
ss -ltnp | grep 3080एक सही परिणाम लूपबैक पते को दर्शाता है:
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 हर इंटरफ़ेस पर है, जिसमें पब्लिक इंटरफ़ेस भी शामिल है। इसे रोकें और कुछ भी और करने से पहले बाइंड (bind) को ठीक करें। यदि ss सॉकेट को प्रिंट करता है लेकिन users: फ़ील्ड को खाली छोड़ देता है, तो इसे sudo के साथ चलाएं, क्योंकि अन्यथा किसी अन्य उपयोगकर्ता के स्वामित्व वाले सॉकेट के लिए प्रोसेस का नाम छिपा रहता है।
जब टनल शुरू होने से मना कर दे
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 पर ब्राउज़ करें जबकि हार्नेस 3080 पर लिसन करना जारी रखेगा। दोनों नंबरों का मेल खाना कभी आवश्यक नहीं है।
यदि टनल शुरू हो जाती है लेकिन ब्राउज़र कनेक्शन अस्वीकार होने या खाली उत्तर की रिपोर्ट करता है, तो ट्रैफ़िक VPS तक तो पहुँचा लेकिन दूसरी तरफ कुछ नहीं मिला। या तो dsh बंद हो गया है, या उसने किसी अलग पोर्ट को बाइंड किया है। सर्वर पर ss -ltnp | grep 3080 के साथ जांचें।
एक और बात जो लोगों को यहाँ परेशान करती है। एक फॉरग्राउंड npx @deepseek-ai/dsh web तब मर जाता है जब उसका शेल बंद हो जाता है, इसलिए जैसे ही आप लॉग आउट करते हैं हार्नेस रुक जाता है। इसे tmux के अंदर या systemd यूजर सर्विस के तहत शुरू करें, जो कि VPS पर कोडिंग एजेंट को चालू रखना में हल की गई समस्या के समान है। जब आप SSH साइड पर काम कर रहे हों, तो अपने VPS पर SSH को सुरक्षित करना पहले करना उचित है, क्योंकि टनल आपके SSH लॉगिन को एजेंट के लिए एकमात्र द्वार बना देती है।
इसे एक private overlay network के माध्यम से एक्सेस करें
एक overlay network आपके VPS और आपके लैपटॉप को एक ऐसे private network पर addresses देता है जिससे केवल आपके उपकरण जुड़ते हैं। Tailscale एक सामान्य विकल्प है, और इसका serve command इस स्थिति के लिए बिल्कुल उपयुक्त है: tailscaled VPS पर चलता है और खुद को localhost:3080 से जोड़ता है, इसलिए harness loopback पर ही रहता है और आपको dsh के configuration में कुछ भी बदलने की आवश्यकता नहीं होती।
tailscale serve --bg localhost:3080
tailscale serve statusइसके बाद UI आपके tailnet के भीतर आपकी मशीन के नाम पर, HTTPS के माध्यम से एक्सेस किया जा सकता है, जिसमें public interface पर कोई भी port खुला नहीं होता। इसके लिए आपके tailnet के लिए HTTPS certificates का सक्षम होना आवश्यक है, अन्यथा serve के पास प्रस्तुत करने के लिए कोई certificate नहीं होगा। इसे वापस हटाने के लिए, off के साथ command को दोहराएं:
tailscale serve --https=443 offserve का उपयोग करें, कभी भी funnel का नहीं। Funnel उसी target को public internet पर प्रकाशित कर देता है, जिससे आप वापस एक open port पर unauthenticated agent runtime की स्थिति में आ जाते हैं। ये दोनों commands दिखने में लगभग एक जैसे हैं और विपरीत कार्य करते हैं, इसलिए किसी को भी टाइप करने से पहले Tailscale Serve और Funnel के बीच का अंतर पढ़ें। Tailscale एक private network के रूप में सेटअप की पूरी प्रक्रिया को कवर करता है।
इसे एक ऐसे reverse proxy के माध्यम से एक्सेस करें जो पासवर्ड की जाँच करता है
यह वह विकल्प है जो वास्तव में एक port को इंटरनेट पर पब्लिश करता है, इसलिए authentication ही वह एकमात्र बाधा है जो किसी अनजान व्यक्ति और आपके सर्वर पर command execution के बीच खड़ी है। इसे तब चुनें जब कई लोगों को UI की आवश्यकता हो और हर किसी के लिए अलग tunnel बनाना अव्यावहारिक हो।
Harness 127.0.0.1:3080 पर चलता है। nginx उसी बॉक्स पर चलता है, इसलिए यह loopback तक पहुँच सकता है, और यह एक certificate तथा पासवर्ड फ़ाइल के साथ 443 पर listen करता है।
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;
}
}पासवर्ड फ़ाइल बनाएँ और reload करें:
sudo apt install -y apache2-utils
sudo htpasswd -c /etc/nginx/dsh.htpasswd you
sudo nginx -t && sudo systemctl reload nginxnginx -t को syntax is ok और उसके बाद test is successful प्रिंट करना चाहिए। एक खराब फ़ाइल के साथ reload विफल हो जाता है और चल रहे configuration को वैसा ही छोड़ देता है, इसलिए आँख बंद करके restart करने के बजाय error को पढ़ें।
उनमें से तीन proxy लाइनें केवल सजावट नहीं हैं। Upgrade और Connection headers WebSocket handshake को अनुमति देते हैं, और उनके बिना पेज लोड तो होता है लेकिन कभी अपडेट नहीं होता। proxy_read_timeout 3600s 60 सेकंड के डिफ़ॉल्ट को बदल देता है, जो अन्यथा एक लंबे agent run को रिस्पॉन्स के बीच में ही काट देता है और UI को फ्रीज दिखाता है। proxy_buffering off मॉडल आउटपुट को ब्राउज़र तक पहुँचते ही भेज देता है, बजाय इसके कि रिस्पॉन्स पूरा होने तक उसे रोक कर रखे। एक nginx reverse proxy कॉन्फ़िगरेशन, लाइन-दर-लाइन बाकी चीजों की व्याख्या करता है, और nginx, Caddy और Traefik के बीच चयन स्वचालित certificates के साथ यही काम करने के बारे में बताता है।
आप चाहे कोई भी proxy चुनें, 3080 को firewall पर बंद रखें, ताकि अंदर आने का एकमात्र रास्ता authenticated proxy ही हो। ufw firewall की मूल बातें नियमों को कवर करती हैं। TLS पर basic authentication एक न्यूनतम आवश्यकता है, न कि एक पूर्ण सुरक्षा मॉडल: जिसके पास वह पासवर्ड है, उसके पास आपके सर्वर का shell है। जब संभव हो, tunnel को प्राथमिकता दें।
dsh web जिस port पर listen करता है, उसे कैसे बदलें?
--port वेब एप्लिकेशन से संबंधित है, न कि लॉन्चर से। CLI डॉक्यूमेंटेशन में इसका उदाहरण सीधे दिया गया है:
dsh --profile web --port 8080dsh web, --profile web का एक alias है, इसलिए dsh web --port 8080 वही कमांड है। लॉन्चर केवल अपने flags को पार्स करता है और उनके बाद आने वाली हर चीज़ को बूट किए गए प्रोफाइल को सौंप देता है। इसलिए लॉन्चर के flags पहले आते हैं, और लॉन्चर द्वारा न पहचाना गया पहला टोकन एप्लिकेशन के arguments की शुरुआत करता है। --port को हमेशा प्रोफाइल के बाद रखें, पहले कभी नहीं।
कमांड द्वारा प्रिंट किए गए URL को पढ़ें, न कि यह मान लें कि वह क्या है, क्योंकि वह लाइन उस पते को दर्शाती है जिस पर सर्वर वास्तव में bind हुआ है। फिर अपने टनल के अंतिम फ़ील्ड को उसके अनुसार अपडेट करें:
ssh -N -L 3080:127.0.0.1:8080 you@your-vpsस्थायी बदलाव के लिए, पोर्ट कमांड लाइन के बजाय प्रोफाइल कॉन्फ़िगरेशन में रहता है। web और headless प्रोफाइल पहली बार उपयोग किए जाने पर ~/.dsh के अंतर्गत दिए गए टेम्प्लेट से स्वतः इनिशियलाइज़ हो जाते हैं। यह देखने के लिए कि सभी लेयर्स के जुड़ने के बाद वास्तव में क्या प्रभावी है:
dsh --dump-configवेबसर्वर प्लगइन में केवल दो keys होती हैं, host और port। port को 0 पर सेट करने से ऑपरेटिंग सिस्टम से एक खाली पोर्ट मांगा जाता है, जिसे "शून्य का अर्थ OS द्वारा असाइन किया गया पोर्ट है" के रूप में प्रलेखित किया गया है। यह सुनिश्चित करता है कि आप कभी भी पोर्ट conflict का सामना न करें, लेकिन यह टनल के लिए उपयुक्त नहीं है, क्योंकि हर रीस्टार्ट पर नंबर बदल जाता है।
dsh 'address already in use' के साथ विफल क्यों होता है?
इसका कारण यह है कि कोई अन्य process पहले से ही उस address और port का उपयोग कर रही है, इसलिए kernel दूसरे bind अनुरोध को अस्वीकार कर देता है। Node इसे इस प्रकार रिपोर्ट करता है:
Error: listen EADDRINUSE: address already in use 127.0.0.1:3080किसी भी बदलाव से पहले यह पता लगाएँ कि वह port किसके पास है:
sudo ss -ltnp | grep 3080users:(("node",pid=1042,fd=21)) field उस process और उसके PID का नाम बताती है। इसका सामान्य उत्तर एक पिछला dsh होता है जिसके बारे में आपको लगा था कि वह बंद हो गया है, लेकिन वह अक्सर किसी detached tmux window में चल रहा होता है। उसे kill 1042 के साथ बंद करें, या नए instance को किसी अलग port पर शुरू करें। ध्यान दें कि 127.0.0.1:3080 और 0.0.0.0:3080 भी आपस में टकराते हैं, क्योंकि सभी interfaces को bind करने का अर्थ loopback को भी कवर करना होता है।
वर्जन को पिन करें, क्योंकि यह एक डेवलपर प्रीव्यू है
README इस बारे में स्पष्ट है: DeepSeek Harness अभी डेवलपर प्रीव्यू में है और इसमें तेजी से बदलाव हो रहे हैं, इसलिए इसमें ऐसे बदलाव आएंगे जो पुरानी compatibility को तोड़ सकते हैं।
npx @deepseek-ai/dsh web हर बार रन करने पर सबसे नया पब्लिश किया गया वर्जन ही लेता है। एक सर्वर जिसे आपने एक हफ्ते से नहीं छुआ है, वह अगली बार लॉन्च होने पर अलग CLI और अलग flags के साथ शुरू हो सकता है। वर्जन को पिन करें ताकि रीस्टार्ट करने पर अपने आप अपग्रेड न हो जाए:
npx @deepseek-ai/dsh@0.1.0-rc.7 webअगस्त 2026 तक पब्लिश किया गया पैकेज वर्जन 0.1.0-rc.7 है। यह जांच लें कि बिना वर्जन पिन किए npx क्या डाउनलोड करेगा, इससे पहले कि आप उसे स्वीकार करें:
npm view @deepseek-ai/dsh versionप्रीव्यू रिलीज के दौरान launcher और web application के बीच flags बदलते रहते हैं। यदि --port उस तरह काम करना बंद कर दे जैसा इस गाइड में बताया गया है, तो अनुमान लगाने के बजाय application से ही उसकी flag सूची मांगें:
dsh --profile web --helpइंस्टॉलेशन, वर्कस्पेस सेटअप और मॉडल की (key) के लिए, VPS पर DeepSeek Harness इंस्टॉल करना देखें। केवल एक्सेस स्टेप के संक्षिप्त विवरण के लिए, VPS पर dsh Web UI तक पहुंचना देखें, जिसमें बिना किसी अतिरिक्त तर्क के केवल टनल सेटअप की जानकारी दी गई है।
FAQ
मैं अपने लैपटॉप ब्राउज़र में http://127.0.0.1:3080 क्यों नहीं खोल पा रहा हूँ?
क्योंकि 127.0.0.1 का अर्थ वह मशीन है जिस पर आप टाइप कर रहे हैं। DeepSeek Harness Web UI, VPS के loopback address से बंधा हुआ है, इसलिए केवल VPS पर चल रही प्रक्रियाएं ही इससे जुड़ सकती हैं। आपके लैपटॉप का अपना अलग loopback है, और वहाँ port 3080 पर कोई भी service listening नहीं है। SSH के माध्यम से ssh -N -L 3080:127.0.0.1:3080 you@your-vps का उपयोग करके port forward करें, और फिर स्थानीय रूप से http://127.0.0.1:3080 लोड करें। -L तर्क का मध्य भाग सर्वर साइड पर resolve होता है, जो इसे harness की ओर निर्देशित करता है।
क्या सार्वजनिक VPS पर dsh Web UI को 0.0.0.0 पर bind करना सुरक्षित है?
नहीं। Web UI उस agent के लिए control surface है जो dsh चलाने वाले उपयोगकर्ता के रूप में shell commands निष्पादित करता है और फ़ाइलें संपादित करता है, और developer preview में कोई login screen नहीं है। सार्वजनिक IP पर सभी interfaces को bind करने का अर्थ है कि port 3080 तक पहुँचने वाला कोई भी व्यक्ति आपके सर्वर पर command निष्पादित कर सकता है। bind को 127.0.0.1 पर रखें, firewall पर 3080 को बंद रखें, और SSH tunnel, private overlay network, या password की आवश्यकता वाले reverse proxy का उपयोग करें।
SSH session बंद करने के बाद मैं dsh Web UI को कैसे चालू रखूँ?
Foreground में चल रहा npx @deepseek-ai/dsh web आपके login shell का child होता है, इसलिए shell बंद होते ही वह भी समाप्त हो जाता है। इसे tmux session के अंदर शुरू करें और Ctrl-b d के साथ detach करें, या lingering सक्षम करके इसे systemd user service के रूप में चलाएं। Tunnel और harness स्वतंत्र हैं: आप जब तक चाहें SSH tunnel को हटा और फिर से बना सकते हैं, बशर्ते harness का parent process आपके login से अधिक समय तक जीवित रहे।
nginx के पीछे लंबे agent run के दौरान dsh Web UI क्यों रुक जाता है?
क्योंकि nginx का डिफ़ॉल्ट proxy_read_timeout 60 सेकंड है, इसलिए यह उस connection को बंद कर देता है जो एक मिनट तक कोई डेटा नहीं भेजता, जो कि एक लंबे agent step के दौरान आसानी से हो सकता है। location ब्लॉक में proxy_read_timeout 3600s; सेट करें। proxy_buffering off; जोड़ें ताकि आउटपुट आते ही ब्राउज़र पर स्ट्रीम हो जाए, और WebSocket handshake सफल होने के लिए proxy_http_version 1.1; के साथ Upgrade और Connection हेडर पास करें। इन हेडर्स के बिना पेज लोड तो होता है लेकिन कोई अपडेट प्राप्त नहीं होता।