dsh web-এ http://127.0.0.1:3080 কেন দেখায়
dsh কেন http://127.0.0.1:3080 দেখায় তা জানুন। Web UI শুধু localhost-এ bind থাকলে SSH tunnel দিয়ে নিরাপদে খুলুন, 3080 প্রকাশের ঝুঁকিও বুঝুন।
What dsh web: http://127.0.0.1:3080 বোঝায়
VPS-এ DeepSeek Harness web profile চালু করলে এটি দুটি লাইন দেখিয়ে অপেক্ষা করে:
dsh web: http://127.0.0.1:3080
Ready.127.0.0.1 হলো loopback address। কোনো মেশিন নিজেকেই সংযোগ করার জন্য এই address ব্যবহার করে। 127.0.0.1-এ bind করা socket শুধু একই মেশিনের process থেকে connection গ্রহণ করে; অন্য কোথাও থেকে নয়। তাই ওই লাইনটি একই সঙ্গে দুটি বিষয় জানায়: Web UI কোথায় listening করছে এবং কে এতে পৌঁছাতে পারবে। শুধু যে মেশিনে dsh চলছে, সেটিই এতে পৌঁছাতে পারে।
এই কারণে laptop-এর browser-এ URL paste করলে কিছু ঘটে না। আপনার laptop-এর 127.0.0.1 হলো আপনার laptop নিজেই। Harness VPS-এর 127.0.0.1-এ listening করছে, যা ভিন্ন loopback stack-সহ একটি ভিন্ন মেশিন। কোনো কিছু নষ্ট হয়নি। আপনাকে connection-টি অন্য মেশিনে পৌঁছে দিতে হবে।
অফিশিয়াল README-তে default স্পষ্টভাবে বলা আছে: "The command starts the Web UI, served at http://127.0.0.1:3080 by default." Bind address আসে webserver host plugin @deepseek-ai/dsh-host-webserver থেকে। এর host key-এর documentation-এ লেখা আছে: "Listen host; the two supported values are loopback and all-interfaces"। আপনি পরিবর্তন না করলে loopback-ই ব্যবহৃত হয়। Port আপনার কাছে নতুন হলে, Linux-এ port কীভাবে কাজ করে-এ address-plus-port model ব্যাখ্যা করা হয়েছে, যার ওপর পুরো বিষয়টি নির্ভর করে।
Web UI কেন শুধু localhost-এ bind থাকে
dsh একটি agent harness। Browser tab এমন একটি process-এর control surface, যা shell command চালায়, আপনার বেছে নেওয়া workspace directory-তে file পড়ে ও লেখে এবং আপনার model API key ব্যবহার করে। যে কেউ ওই page load করতে পারলে dsh যে user হিসেবে চলছে, সেই user-এর অধিকারেই এসব কাজ করতে পারবে।
তাই port 3080 শুধু read-only dashboard নয়। ওই page load করলেই server-এ command execution-এর সুযোগ পাওয়া যায়।
Web UI খুললে সরাসরি session list দেখা যায়। কোনো login prompt নেই, কারণ developer preview-তে user account বা remote authentication নেই। Loopback-এ এটি স্বাভাবিক: operating system-ই access control হিসেবে কাজ করে এবং শুধু local process সংযোগ করতে পারে। একই server-কে public IP-সহ একটি VPS-এ 0.0.0.0-এ bind করলে ওই page পুরো Internet-এর অনুরোধের উত্তর দেবে, সামনে কোনো সুরক্ষা স্তর ছাড়াই। Automated scanner-গুলো নিয়মিত uncommon port স্ক্যান করে। তাই published 3080-কে ইতিমধ্যে শনাক্ত হয়েছে বলে ধরে নিন।
আপনার firewall-এ port 3080 খুলবেন না এবং public VPS-এ webserver-এরhost-কে0.0.0.0সেট করবেন না। এই সংমিশ্রণ server-এ সংযোগকারী প্রথম ব্যক্তিকেই command execution-এর সুযোগ দেয়।
Server-এ চালানো প্রতিটি agent runtime-এর ক্ষেত্রেই একই যুক্তি প্রযোজ্য। তাই VPS-এ coding agent নিরাপদে চালানো একই নিয়ম দিয়ে শুরু হয়: agent-এর control port private থাকে এবং আপনার বিশ্বস্ত কোনো ব্যবস্থা আপনাকে সেটিতে পৌঁছে দেয়।
আমি কীভাবে আমার laptop থেকে dsh Web UI খুলব?
এটি করার 3টি নিরাপদ উপায় আছে। প্রতিটি উপায়েই harness loopback-এ bind থাকে।
- একটি SSH tunnel। Public interface-এ নতুন কোনো service listening করে না, এবং আপনার কাছে ইতিমধ্যেই credentials আছে। এটিই ব্যবহার করুন।
- একটি private overlay network। এর মাধ্যমে আপনার নিজস্ব device-গুলো থেকে UI-তে পৌঁছানো যায়, কিন্তু অন্য সবার কাছ থেকে এটি অদৃশ্য থাকে।
- একটি reverse proxy, যা TLS (transport layer security) termination করে এবং কোনো request forward করার আগে password চায়।
পার্থক্য হলো, আপনার browser-কে loopback-এ পৌঁছে দেয় কোন মাধ্যম। কোনো পদ্ধতিতেই harness-কে loopback-এর বাইরে bind করা উচিত নয়।
SSH tunnel ব্যবহার করে এটি অ্যাক্সেস করুন
এটি VPS-এ নয়, আপনার laptop-এ চালান:
ssh -N -L 3080:127.0.0.1:3080 you@your-vpsএটি চালু রাখুন। তারপর আপনার local browser-এ http://127.0.0.1:3080 খুলুন। Web UI লোড হবে।
-L argument-এ colon দিয়ে পৃথক করা তিনটি field থাকে। প্রথমটি laptop-এ খোলার port। দ্বিতীয় ও তৃতীয়টি হলো প্রতিটি connection যে address এবং port-এ forward হবে। গুরুত্বপূর্ণ বিষয় হলো, মাঝের field-এর 127.0.0.1 আপনার traffic VPS-এ পৌঁছানোর পরে VPS-এর SSH server resolve করে। এটি আপনার loopback নয়, VPS-এর loopback। dsh যে address দেখিয়েছে, এটিই সেই address। তাই সরাসরি browser connection ব্যর্থ হলেও tunnel কাজ করে।
-N SSH-কে কোনো remote command চালাতে নিষেধ করে। ফলে shell নয়, শুধু একটি forwarder পাওয়া যায়। নীরবে ব্যর্থ না হয়ে স্পষ্টভাবে error দেখাবে এমন background tunnel-এর জন্য:
ssh -N -f -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -L 3080:127.0.0.1:3080 you@your-vps-f authentication শেষ হওয়ার পরে এটিকে background-এ পাঠায়। ExitOnForwardFailure=yes দেখতে যতটা সাধারণ মনে হয়, তার চেয়ে বেশি গুরুত্বপূর্ণ। এটি না থাকলে forward সেট আপ না হলেও SSH সফলভাবে connect করে। ফলে session চালু থাকে, কিন্তু tunnel নিষ্ক্রিয় থাকে এবং কোনো warning দেখা যায় না। ServerAliveInterval=30 প্রতি 30 সেকেন্ডে একটি keepalive পাঠায়। এতে café এবং hotel router-এর NAT (network address translation) timeout হলেও idle tunnel চালু থাকে।
আপনি যা দেখতে পাবেন
VPS-এ সত্যিই কোন address ও port listening করছে তা নিশ্চিত করুন:
ss -ltnp | grep 3080স্বাভাবিক ফলাফলে loopback address দেখা যাবে:
LISTEN 0 511 127.0.0.1:3080 0.0.0.0:* users:(("node",pid=1042,fd=21))local address column-এ যদি 0.0.0.0:3080 দেখা যায়, তাহলে Web UI সব interface-এ, public interface-সহ, bind করা আছে। অন্য কিছু করার আগে এটি বন্ধ করুন এবং bind address ঠিক করুন। ss socket দেখালেও users: field খালি রাখলে sudo দিয়ে চালান। অন্য user-এর মালিকানাধীন socket-এর process name না হলে গোপন থাকে।
Tunnel চালু হতে না চাইলে
SSH এই message দেখিয়ে বন্ধ হয়ে যায়:
bind [127.0.0.1]:3080: Address already in use
channel_setup_fwd_listener_tcpip: cannot listen to port: 3080এটি server-এর নয়, আপনার laptop-এর সমস্যা। কোনো local process ইতিমধ্যে port 3080 ব্যবহার করছে। সাধারণত আগের কোনো tunnel বন্ধ করতে ভুলে গেলে এমন হয়। এর বদলে একটি খালি local port বেছে নিন:
ssh -N -L 3081:127.0.0.1:3080 you@your-vpsশুধু প্রথম field পরিবর্তিত হয়েছে। তাই এখন http://127.0.0.1:3081-এ browse করবেন, আর harness 3080-এ listening চালিয়ে যাবে। দুটি সংখ্যার এক হওয়ার প্রয়োজন নেই।
Tunnel চালু হলেও browser যদি refused connection বা empty reply দেখায়, তাহলে traffic VPS-এ পৌঁছেছে, কিন্তু far end-এ কোনো service পাওয়া যায়নি। হয় dsh বন্ধ হয়ে গেছে, নয়তো অন্য port-এ bind করেছে। server-এ ss -ltnp | grep 3080 দিয়ে পরীক্ষা করুন।
এখানে আরেকটি বিষয় সমস্যা তৈরি করে। foreground-এ চালানো npx @deepseek-ai/dsh web shell বন্ধ হলে বন্ধ হয়ে যায়। তাই আপনি logout করার সঙ্গে সঙ্গে harness-ও থেমে যায়। এটিকে tmux-এর ভিতরে অথবা systemd user service হিসেবে চালু করুন। এটি VPS-এ coding agent চালু রাখা-তে সমাধান করা একই সমস্যা। SSH অংশে কাজ করার সময় আপনার VPS-এ SSH hardening করা আগে করা উচিত। কারণ tunnel আপনার SSH login-কে agent-এ প্রবেশের একমাত্র পথ বানায়।
একটি private overlay network-এর মাধ্যমে এটি অ্যাক্সেস করুন
একটি overlay network আপনার VPS এবং laptop-কে এমন একটি private network-এ address দেয়, যেখানে শুধু আপনার ডিভাইসগুলো যুক্ত হয়। Tailscale এ ক্ষেত্রে সাধারণ পছন্দ, এবং এর serve command এই কাজের জন্য উপযুক্ত: tailscaled VPS-এ চলে এবং নিজেই localhost:3080-এর সঙ্গে সংযোগ করে। ফলে harness loopback-এই থাকে, এবং dsh কীভাবে configured আছে তাতে কোনো পরিবর্তন করতে হয় না।
tailscale serve --bg localhost:3080
tailscale serve statusএরপর public interface-এ কোনো port খোলা না রেখেই আপনার tailnet-এর ভেতরে থাকা মেশিনের name ব্যবহার করে HTTPS-এর মাধ্যমে UI-তে পৌঁছানো যায়। এর জন্য আপনার tailnet-এর জন্য HTTPS certificate enabled থাকতে হবে। তা না হলে serve উপস্থাপনের জন্য কোনো certificate পাবে না। এটি বন্ধ করতে off দিয়ে command-টি আবার চালান:
tailscale serve --https=443 offserve ব্যবহার করুন, funnel নয়। Funnel একই target public internet-এ প্রকাশ করে। এতে আপনি আবার open port-এ unauthenticated agent runtime-এর অবস্থায় ফিরে যাবেন। দুটি command দেখতে প্রায় একই, কিন্তু তাদের কাজ বিপরীত। তাই যেকোনো একটি টাইপ করার আগে Tailscale Serve এবং Funnel-এর পার্থক্য পড়ুন। একটি private network হিসেবে Tailscale-এ সেটআপের বিস্তারিত রয়েছে।
Reverse proxy দিয়ে password যাচাই করে এতে প্রবেশ করুন
এই বিকল্পে সত্যিই Internet-এ একটি port প্রকাশ করা হয়। তাই authentication-ই অপরিচিত কাউকে আপনার সার্ভারে command execution থেকে আটকানোর একমাত্র বাধা। একাধিক ব্যক্তির UI ব্যবহার করার প্রয়োজন হলে এবং প্রত্যেকের জন্য আলাদা tunnel চালানো বাস্তবসম্মত না হলে এই পদ্ধতি বেছে নিন।
Harness 127.0.0.1:3080-এ চলতে থাকে। nginx একই box-এ চলে, তাই এটি loopback-এ পৌঁছাতে পারে। nginx certificate এবং password file ব্যবহার করে 443 port-এ 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;
}
}Password file তৈরি করে 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 দেখানোর কথা। Broken file থাকলে reload ব্যর্থ হয় এবং চলমান configuration অপরিবর্তিত থাকে। তাই অন্ধভাবে restart না করে error পড়ুন।
Proxy-এর ওই তিনটি line শুধু আনুষ্ঠানিকতা নয়। Upgrade এবং Connection header WebSocket handshake সম্পন্ন হতে দেয়। এগুলো না থাকলে page load হয়, কিন্তু আর update হয় না। proxy_read_timeout 3600s 60 second-এর default মান প্রতিস্থাপন করে। তা না হলে দীর্ঘ agent run মাঝপথে কেটে যায় এবং UI স্থির হয়ে আছে বলে মনে হয়। proxy_buffering off model output response সম্পূর্ণ হওয়া পর্যন্ত আটকে না রেখে আসার সঙ্গে সঙ্গে browser-এ পাঠায়। nginx reverse proxy configuration, line by line-এ বাকি বিষয়টি ব্যাখ্যা করা হয়েছে। nginx, Caddy এবং Traefik-এর মধ্যে নির্বাচন করা অংশে automatic certificate ব্যবহার করে একই কাজ করার পদ্ধতি দেওয়া আছে।
কোন proxy বেছে নেন তা যাই হোক, firewall-এ 3080 বন্ধ রাখুন। এতে প্রবেশের একমাত্র পথ authenticated proxy হয়ে থাকে। ufw firewall-এর প্রাথমিক বিষয়গুলি-তে rule-গুলো ব্যাখ্যা করা হয়েছে। TLS-এর ওপর Basic authentication একটি ন্যূনতম সুরক্ষা, সম্পূর্ণ security model নয়। যার কাছে ওই password আছে, তার কাছে আপনার সার্ভারের shell-এ প্রবেশাধিকার আছে। সম্ভব হলে tunnel ব্যবহার করুন।
dsh যে port-এ web শোনে, সেটি কীভাবে পরিবর্তন করব?
--port launcher-এর নয়, web application-এর অংশ। CLI documentation-এ এর সরাসরি উদাহরণ দেওয়া আছে:
dsh --profile web --port 8080dsh web হলো --profile web-এর alias, তাই dsh web --port 8080 একই command। Launcher শুধু নিজের flags parse করে এবং এরপরের সবকিছু booted profile-এর কাছে পাঠায়। তাই launcher flags আগে দিতে হবে, আর launcher যে প্রথম token চিনতে পারে না, সেখান থেকেই application arguments শুরু হয়। --port profile-এর পরে দিন, কখনো তার আগে নয়।
Command যে URL print করে, সেটি পড়ুন। অনুমান করবেন না, কারণ ওই লাইনে server যে address-এ সত্যিই bind করেছে, সেটি দেখানো হয়। এরপর tunnel-এর শেষ field-টি সেই অনুযায়ী আপডেট করুন:
ssh -N -L 3080:127.0.0.1:8080 you@your-vpsস্থায়ী পরিবর্তনের জন্য port command line-এ নয়, profile configuration-এ থাকে। web এবং headless profile প্রথমবার ব্যবহারের সময় ~/.dsh-এর অধীনে shipped template থেকে স্বয়ংক্রিয়ভাবে initialize হয়। সব layer compose হওয়ার পরে কার্যকর configuration দেখতে:
dsh --dump-configWebserver plugin ঠিক দুটি key প্রকাশ করে: host এবং port। port-এর মান 0 সেট করলে operating system-এর কাছে একটি free port চাওয়া হয়। Documentation-এ বলা আছে, “zero requests an OS-assigned port”। এতে port conflict হওয়ার সম্ভাবনা থাকে না। তবে tunnel-এর জন্য এটি উপযুক্ত নয়, কারণ প্রতিটি restart-এ port number বদলে যায়।
dsh-এ address already in use ত্রুটি কেন হয়?
অন্য একটি process ইতিমধ্যে ওই address ও port দখল করে রাখে। তাই kernel দ্বিতীয় bind প্রত্যাখ্যান করে। Node এটি এভাবে দেখায়:
Error: listen EADDRINUSE: address already in use 127.0.0.1:3080কোনো পরিবর্তন করার আগে কোন processটি address ধরে রেখেছে তা খুঁজে বের করুন:
sudo ss -ltnp | grep 3080users:(("node",pid=1042,fd=21)) field-এ process এবং তার PID-এর নাম থাকে। সাধারণত কারণটি হলো আগের একটি dsh, যেটি বন্ধ হয়েছে বলে আপনি ধরে নিয়েছিলেন। সেটি প্রায়ই বিচ্ছিন্ন tmux window-তে এখনও চলতে থাকে। kill 1042 দিয়ে সেটি বন্ধ করুন। অথবা নতুন instance-টি অন্য port-এ চালু করুন। মনে রাখবেন, 127.0.0.1:3080 এবং 0.0.0.0:3080 একে অপরের সঙ্গেও সংঘর্ষ করে, কারণ সব interface-এ bind করলে loopback-ও অন্তর্ভুক্ত হয়।
সংস্করণ নির্দিষ্ট করুন, কারণ এটি developer preview
README-তে বিষয়টি স্পষ্টভাবে বলা আছে: DeepSeek Harness বর্তমানে developer preview পর্যায়ে রয়েছে এবং দ্রুত পরিবর্তন করা হচ্ছে। এর ফলে compatibility-breaking পরিবর্তন আসতে পারে।
npx @deepseek-ai/dsh web প্রতিবার চালানোর সময় সর্বশেষ প্রকাশিত সংস্করণে resolve হয়। এক সপ্তাহ ধরে অপরিবর্তিত থাকা কোনো সার্ভার পরবর্তীবার চালু হলে ভিন্ন flag-সহ আলাদা CLI শুরু করতে পারে। Restart যেন upgrade না হয়ে যায়, তাই সংস্করণ নির্দিষ্ট করুন:
npx @deepseek-ai/dsh@0.1.0-rc.7 webAugust 2026 অনুযায়ী প্রকাশিত package-এর সংস্করণ 0.1.0-rc.7। এটি গ্রহণ করার আগে bare npx কোন সংস্করণ আনবে তা পরীক্ষা করুন:
npm view @deepseek-ai/dsh versionPreview release-গুলোর মধ্যে launcher এবং web application-এর মধ্যে flag স্থানান্তরিত হতে পারে। --port যদি এই guide-এ বর্ণিতভাবে কাজ করা বন্ধ করে, অনুমান না করে application-এর নিজস্ব flag list দেখুন:
dsh --profile web --helpশুধু install, workspace setup এবং model key-এর জন্য VPS-এ DeepSeek Harness ইনস্টল করা দেখুন। শুধু access ধাপের সংক্ষিপ্ত নির্দেশনার জন্য VPS-এ dsh Web UI-তে পৌঁছানো tunnel প্রক্রিয়াটি ব্যাখ্যা করে; reasoning অংশটি এতে নেই।
FAQ
কেন আমার laptop browser-এ http://127.0.0.1:3080 খুলতে পারি না?
কারণ 127.0.0.1 বলতে আপনি যে machine-এ কমান্ড লিখছেন সেটিকে বোঝায়। DeepSeek Harness Web UI VPS-এর loopback address-এ bind করা, তাই শুধু VPS-এর process-গুলো এতে connect করতে পারে। আপনার laptop-এর loopback আলাদা, এবং সেখানে port 3080-এ কোনো process listening করছে না। ssh -N -L 3080:127.0.0.1:3080 you@your-vps ব্যবহার করে SSH-এর মাধ্যমে port forward করুন, তারপর locally http://127.0.0.1:3080 load করুন। -L argument-এর মাঝের field server side-এ resolve হয়। এ কারণেই এটি harness-কে নির্দেশ করে।
Public VPS-এ dsh Web UI-কে 0.0.0.0-এ bind করা কি নিরাপদ?
না। Web UI এমন একটি agent-এর control surface, যা dsh হিসেবে চলা user-এর হয়ে shell command চালায় এবং file edit করে। Developer preview-তে কোনো login screen-ও নেই। Public IP-র সব interface-এ bind করলে port 3080-এ পৌঁছাতে পারে এমন যে কেউ আপনার server-এ command execute করতে পারবে। Bind 127.0.0.1-এ রাখুন, firewall-এ 3080 বন্ধ রাখুন, এবং password প্রয়োজন এমন SSH tunnel, private overlay network অথবা reverse proxy ব্যবহার করুন।
SSH session বন্ধ করার পর dsh Web UI কীভাবে চালু রাখব?
Foreground npx @deepseek-ai/dsh web আপনার login shell-এর child process। তাই সেই shell exit করলে এটিও killed হয়। একটি tmux session-এর মধ্যে এটি start করুন এবং Ctrl-b d দিয়ে detach করুন। অথবা lingering enabled রেখে systemd user service হিসেবে চালান। Tunnel এবং harness স্বাধীন। Harness চলমান থাকলে আপনি যতবার ইচ্ছা SSH tunnel বন্ধ করে আবার তৈরি করতে পারেন। এর জন্য harness-এর এমন একটি parent থাকতে হবে, যা আপনার login session-এর চেয়ে বেশি সময় চলবে।
nginx-এর পেছনে দীর্ঘ agent run চলার সময় dsh Web UI মাঝপথে freeze হয় কেন?
কারণ nginx-এর default proxy_read_timeout হলো 60 seconds। এক মিনিট কোনো data না এলে nginx connection বন্ধ করে দেয়। দীর্ঘ agent step-এ এটি সহজেই ঘটে। proxy_read_timeout 3600s;-কে location block-এ set করুন। Output আসার সঙ্গে সঙ্গে browser-এ stream করার জন্য proxy_buffering off; যোগ করুন। WebSocket handshake সফল করতে proxy_http_version 1.1; দিয়ে Upgrade এবং Connection header পাঠান। এই header না থাকলে page load হয়, কিন্তু কোনো update আর পায় না।