วิธีเข้าใช้งาน dsh web ที่ http://127.0.0.1:3080
ข้อความ http://127.0.0.1:3080 ปรากฏขึ้นเพราะ Web UI ผูกกับ localhost เท่านั้น เรียนรู้วิธีเชื่อมต่อผ่าน SSH tunnel อย่างปลอดภัยและเหตุผลที่ไม่ควรเปิดพอร์ต 3080 ออกสู่สาธารณะ
ความหมายของ dsh web: http://127.0.0.1:3080
เมื่อคุณเริ่มใช้งานโปรไฟล์เว็บของ DeepSeek Harness บน VPS ระบบจะแสดงข้อความสองบรรทัดแล้วหยุดรอ:
dsh web: http://127.0.0.1:3080
Ready.127.0.0.1 คือ loopback address ซึ่งเป็นที่อยู่ที่เครื่องใช้สำหรับติดต่อสื่อสารกับตัวเอง ซ็อกเก็ตที่ผูกไว้กับ 127.0.0.1 จะยอมรับการเชื่อมต่อจากโพรเซสที่อยู่บนเครื่องเดียวกันเท่านั้น ไม่รับจากที่อื่น ดังนั้นบรรทัดนั้นจึงบอกข้อมูลสองอย่างพร้อมกัน คือตำแหน่งที่ Web UI กำลังรอรับการเชื่อมต่อ และใครบ้างที่ได้รับอนุญาตให้เข้าถึงได้ ซึ่งก็คือเฉพาะเครื่องที่ dsh กำลังทำงานอยู่เท่านั้น
นี่คือเหตุผลว่าทำไม URL ถึงไม่ทำงานเมื่อคุณนำไปวางในเบราว์เซอร์บนแล็ปท็อปของคุณ เพราะ 127.0.0.1 ของแล็ปท็อปคุณคือตัวแล็ปท็อปเอง ในขณะที่ Harness กำลังรอรับการเชื่อมต่ออยู่ที่ 127.0.0.1 ของ VPS ซึ่งเป็นคนละเครื่องและมี loopback stack แยกจากกัน ไม่ได้มีอะไรเสียหาย คุณเพียงแค่ต้องส่งผ่านการเชื่อมต่อข้ามมาเท่านั้น
README อย่างเป็นทางการระบุค่าเริ่มต้นไว้อย่างชัดเจนว่า: "คำสั่งนี้จะเริ่มการทำงานของ Web UI โดยให้บริการที่ http://127.0.0.1:3080 เป็นค่าเริ่มต้น" ที่อยู่สำหรับผูก (bind address) มาจากปลั๊กอิน webserver host คือ @deepseek-ai/dsh-host-webserver ซึ่งคีย์ host ได้รับการระบุไว้ในเอกสารว่า "Listen host; ค่าที่รองรับมีสองค่าคือ loopback และ all-interfaces" คุณจะได้รับค่าเป็น loopback เว้นแต่คุณจะเข้าไปเปลี่ยนมัน หากคุณยังไม่คุ้นเคยกับพอร์ต การทำงานของพอร์ตบน Linux จะอธิบายถึงรูปแบบที่อยู่รวมกับพอร์ตซึ่งเป็นพื้นฐานของเรื่องทั้งหมดนี้
เหตุผลที่ Web UI ผูกไว้กับ localhost เท่านั้น
dsh เป็นเครื่องมือสำหรับจัดการเอเจนต์ แท็บเบราว์เซอร์ทำหน้าที่เป็นส่วนควบคุมสำหรับกระบวนการที่รันคำสั่ง shell, อ่านและเขียนไฟล์ในไดเรกทอรี workspace ที่คุณเลือก และใช้ API key ของโมเดลของคุณ ใครก็ตามที่สามารถโหลดหน้านั้นได้จะสามารถทำทุกอย่างได้ในฐานะผู้ใช้ที่รัน dsh
ดังนั้นพอร์ต 3080 จึงไม่ใช่แดชบอร์ดแบบอ่านได้อย่างเดียว การโหลดหน้านั้นเท่ากับการอนุญาตให้รันคำสั่งบนเซิร์ฟเวอร์ได้
เมื่อเปิด Web UI คุณจะเข้าสู่รายการเซสชันทันที โดยไม่มีหน้าจอให้ล็อกอิน เนื่องจากเวอร์ชัน developer preview ยังไม่มีระบบบัญชีผู้ใช้และการยืนยันตัวตนจากระยะไกล การผูกไว้กับ loopback จึงมีความสอดคล้องในแง่ความปลอดภัย กล่าวคือระบบปฏิบัติการทำหน้าที่เป็นตัวควบคุมการเข้าถึง และมีเพียงกระบวนการภายในเครื่องเท่านั้นที่เข้าถึงได้ หากคุณผูกเซิร์ฟเวอร์เดียวกันนี้เข้ากับ 0.0.0.0 บน VPS ที่มี public IP หน้าเว็บเดียวกันนั้นจะตอบสนองต่อทุกคนบนอินเทอร์เน็ตโดยไม่มีการป้องกันใดๆ อยู่เบื้องหน้า บอทสแกนอัตโนมัติจะกวาดหาพอร์ตที่ไม่ธรรมดาอยู่ตลอดเวลา ดังนั้นให้ถือว่าพอร์ต 3080 ที่เปิดเผยสู่สาธารณะนั้นถูกค้นพบแล้วแน่นอน
ห้ามเปิดพอร์ต 3080 ในไฟร์วอลล์ของคุณ และห้ามตั้งค่าเว็บเซิร์ฟเวอร์hostให้เป็น0.0.0.0บน VPS สาธารณะ การทำเช่นนั้นเท่ากับเป็นการมอบสิทธิ์การรันคำสั่งบนเซิร์ฟเวอร์ของคุณให้กับใครก็ตามที่เชื่อมต่อเข้ามาเป็นคนแรก
เหตุผลเดียวกันนี้ใช้กับรันไทม์ของเอเจนต์ทุกตัวที่คุณติดตั้งบนเซิร์ฟเวอร์ ซึ่งเป็นเหตุผลว่าทำไม การรัน coding agent บน VPS อย่างปลอดภัย จึงเริ่มต้นด้วยกฎข้อเดียวกัน นั่นคือพอร์ตควบคุมของเอเจนต์ต้องเป็นส่วนตัว และคุณต้องใช้เครื่องมือที่คุณเชื่อถือในการเข้าถึงพอร์ตนั้นแทน
ฉันจะเปิดใช้งาน Web UI ของ dsh จากแล็ปท็อปได้อย่างไร
มีวิธีที่เหมาะสมอยู่ 3 วิธี และทุกวิธีจะยังคงรักษาการเชื่อมต่อของ harness ไว้ที่ loopback ดังเดิม
- การทำ SSH tunnel: ไม่มีการเปิดพอร์ตใหม่บน public interface และคุณมีข้อมูลรับรองการใช้งานอยู่แล้ว นี่คือวิธีที่ควรเลือกใช้
- การใช้ private overlay network: เพื่อให้สามารถเข้าถึง UI ได้จากอุปกรณ์ของคุณเองโดยที่ผู้อื่นไม่สามารถมองเห็นได้
- การใช้ reverse proxy: เพื่อทำ TLS (transport layer security) termination และบังคับให้ใส่รหัสผ่านก่อนที่จะส่งต่อคำขอใดๆ
ความแตกต่างของแต่ละวิธีคือวิธีการนำเบราว์เซอร์ของคุณไปเชื่อมต่อกับ 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 ประกอบด้วยสามส่วนที่คั่นด้วยเครื่องหมายโคลอน ส่วนแรกคือพอร์ตที่จะเปิดบนแล็ปท็อปของคุณ ส่วนที่สองและสามคือที่อยู่และพอร์ตที่จะส่งต่อการเชื่อมต่อแต่ละรายการไปให้ รายละเอียดที่สำคัญคือ 127.0.0.1 ในส่วนกลางจะถูกแก้ไขโดย SSH server บน VPS หลังจากที่ทราฟฟิกของคุณไปถึงที่นั่นแล้ว ซึ่งหมายถึง loopback ของ VPS ไม่ใช่ของคุณ นี่คือที่อยู่ที่ dsh แสดงผลออกมา ซึ่งเป็นเหตุผลว่าทำไม tunnel ถึงใช้งานได้ในขณะที่การเชื่อมต่อผ่านเบราว์เซอร์โดยตรงใช้งานไม่ได้
-N บอกให้ SSH ไม่ต้องรันคำสั่งบนรีโมท คุณจึงได้ตัวส่งต่อโดยไม่มีเชลล์ สำหรับ tunnel ที่ทำงานเบื้องหลังและแจ้งเตือนเมื่อเกิดข้อผิดพลาดแทนที่จะเงียบหายไป:
ssh -N -f -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -L 3080:127.0.0.1:3080 you@your-vps-f จะส่งกระบวนการไปทำงานเบื้องหลังหลังจากยืนยันตัวตนแล้ว ExitOnForwardFailure=yes มีความสำคัญมากกว่าที่เห็น เพราะหากไม่มีมัน SSH จะเชื่อมต่อสำเร็จแม้ว่าจะตั้งค่าการส่งต่อไม่ได้ ทำให้คุณได้เซสชันที่ใช้งานได้แต่ tunnel กลับตายโดยไม่มีการแจ้งเตือน ServerAliveInterval=30 จะส่ง keepalive ทุก 30 วินาที เพื่อให้ tunnel ที่ไม่ได้ใช้งานคงอยู่ได้แม้จะเจอกับ NAT (network address translation) timeout บนเราเตอร์ของร้านกาแฟหรือโรงแรม
สิ่งที่คุณควรเห็น
บน VPS ให้ยืนยันว่ามีอะไรกำลังฟังพอร์ตอยู่จริง:
ss -ltnp | grep 3080ผลลัพธ์ที่ปกติจะระบุที่อยู่ loopback:
LISTEN 0 511 127.0.0.1:3080 0.0.0.0:* users:(("node",pid=1042,fd=21))หากคอลัมน์ที่อยู่ภายใน (local address) แสดงเป็น 0.0.0.0:3080 แทน แสดงว่า Web UI กำลังฟังอยู่ทุกอินเทอร์เฟซรวมถึงอินเทอร์เฟซสาธารณะด้วย ให้หยุดการทำงานและแก้ไขการ bind ก่อนดำเนินการอื่น หาก ss แสดงซ็อกเก็ตแต่ปล่อยให้ช่อง users: ว่างเปล่า ให้รันด้วย sudo เพราะชื่อกระบวนการสำหรับซ็อกเก็ตที่เป็นเจ้าของโดยผู้ใช้อื่นจะถูกซ่อนไว้หากไม่ทำเช่นนั้น
เมื่อ tunnel ปฏิเสธที่จะเริ่มทำงาน
SSH จะแสดงข้อความนี้และออกจากโปรแกรม:
bind [127.0.0.1]:3080: Address already in use
channel_setup_fwd_listener_tcpip: cannot listen to port: 3080ปัญหานี้เกี่ยวกับแล็ปท็อปของคุณ ไม่ใช่เซิร์ฟเวอร์ มีบางอย่างในเครื่องกำลังใช้งานพอร์ต 3080 อยู่ ซึ่งมักจะเป็น tunnel ก่อนหน้าที่คุณลืมปิด ให้เลือกพอร์ตว่างในเครื่องแทน:
ssh -N -L 3081:127.0.0.1:3080 you@your-vpsมีเพียงส่วนแรกเท่านั้นที่เปลี่ยนไป ดังนั้นตอนนี้คุณจึงเข้าถึง http://127.0.0.1:3081 ในขณะที่ตัว harness ยังคงฟังอยู่ที่ 3080 ตัวเลขทั้งสองไม่จำเป็นต้องตรงกัน
หาก tunnel เริ่มทำงานได้แต่เบราว์เซอร์รายงานว่าการเชื่อมต่อถูกปฏิเสธหรือไม่มีการตอบกลับ แสดงว่าทราฟฟิกข้ามไปยัง VPS แล้วแต่ไม่พบปลายทาง อาจเป็นเพราะ dsh ออกจากโปรแกรมไปแล้ว หรือมีการ bind พอร์ตอื่น ให้ตรวจสอบด้วย ss -ltnp | grep 3080 บนเซิร์ฟเวอร์
อีกหนึ่งสิ่งที่มักสร้างปัญหาคือ npx @deepseek-ai/dsh web ที่รันอยู่เบื้องหน้าจะตายเมื่อเชลล์ปิดลง ดังนั้น harness จะหยุดทำงานทันทีที่คุณออกจากระบบ ให้เริ่มทำงานภายใน tmux หรือภายใต้ systemd user service ซึ่งเป็นปัญหาเดียวกันกับที่แก้ไขไว้ใน การรักษาให้ coding agent ทำงานบน VPS ในระหว่างที่คุณกำลังจัดการฝั่ง SSH การ เพิ่มความปลอดภัยให้ SSH บน VPS เป็นสิ่งที่ควรทำก่อน เพราะ tunnel จะทำให้การล็อกอิน SSH ของคุณเป็นประตูเดียวที่เข้าถึง agent ได้
การเข้าถึงผ่านเครือข่าย overlay ส่วนตัว
เครือข่าย overlay ช่วยให้ VPS และแล็ปท็อปของคุณมีที่อยู่บนเครือข่ายส่วนตัวที่มีเพียงอุปกรณ์ของคุณเท่านั้นที่เข้าร่วมได้ Tailscale เป็นตัวเลือกที่นิยมใช้ และคำสั่ง serve ก็เหมาะสมกับกรณีนี้อย่างยิ่ง โดย tailscaled จะทำงานบน VPS และเชื่อมต่อเข้ากับ localhost:3080 ของตัวมันเอง ทำให้ harness ยังคงทำงานอยู่บน loopback และคุณไม่จำเป็นต้องเปลี่ยนแปลงการตั้งค่าใดๆ ของ dsh เลย
tailscale serve --bg localhost:3080
tailscale serve statusจากนั้นคุณจะสามารถเข้าถึง UI ได้ผ่านชื่อเครื่องของคุณภายใน tailnet โดยใช้ HTTPS โดยไม่ต้องเปิดพอร์ตใดๆ บนอินเทอร์เฟซสาธารณะ วิธีนี้จำเป็นต้องเปิดใช้งานใบรับรอง HTTPS สำหรับ tailnet ของคุณ มิฉะนั้น serve จะไม่มีใบรับรองสำหรับแสดงผล หากต้องการยกเลิกการใช้งาน ให้ทำซ้ำคำสั่งเดิมด้วย off:
tailscale serve --https=443 offให้ใช้ serve เท่านั้น ห้ามใช้ funnel โดยเด็ดขาด เนื่องจาก Funnel จะเผยแพร่เป้าหมายเดียวกันออกสู่สาธารณะบนอินเทอร์เน็ต ซึ่งจะทำให้คุณกลับไปอยู่ในสถานะที่ agent ทำงานโดยไม่มีการยืนยันตัวตนบนพอร์ตที่เปิดโล่ง คำสั่งทั้งสองดูคล้ายกันมากแต่ให้ผลลัพธ์ที่ตรงกันข้าม ดังนั้นโปรดอ่าน ความแตกต่างระหว่าง Tailscale Serve และ Funnel ก่อนที่คุณจะพิมพ์คำสั่งใดๆ ทั้งนี้ Tailscale ในฐานะเครือข่ายส่วนตัว ได้อธิบายขั้นตอนการตั้งค่าไว้โดยละเอียดแล้ว
เข้าถึงผ่าน reverse proxy ที่มีการตรวจสอบรหัสผ่าน
นี่คือตัวเลือกที่เปิดพอร์ตสู่สาธารณะจริง ดังนั้นการยืนยันตัวตนจึงเป็นปราการด่านเดียวที่กั้นระหว่างบุคคลภายนอกกับการรันคำสั่งบนเซิร์ฟเวอร์ของคุณ ให้เลือกวิธีนี้เมื่อมีผู้ใช้งานหลายคนต้องการเข้าถึง UI และการทำ tunnel แยกสำหรับแต่ละคนนั้นไม่สะดวก
ตัว harness จะทำงานอยู่บน 127.0.0.1:3080 โดยที่ nginx ทำงานอยู่บนเครื่องเดียวกัน จึงสามารถเข้าถึง loopback ได้ และ nginx จะคอยฟังที่พอร์ต 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 nginxnginx -t ควรแสดงผล syntax is ok ตามด้วย test is successful หากการโหลดใหม่ล้มเหลวเนื่องจากไฟล์มีปัญหา ระบบจะยังคงใช้การตั้งค่าเดิมที่ทำงานอยู่ ดังนั้นให้อ่านข้อความแสดงข้อผิดพลาดแทนการรีสตาร์ทแบบสุ่มสี่สุ่มห้า
บรรทัด proxy สามบรรทัดนั้นไม่ใช่แค่การตกแต่ง แต่ header Upgrade และ Connection ช่วยให้การทำ WebSocket handshake ผ่านไปได้ หากไม่มีบรรทัดเหล่านี้ หน้าเว็บจะโหลดขึ้นมาแต่จะไม่แสดงข้อมูลอัปเดต ส่วน proxy_read_timeout 3600s จะเข้ามาแทนที่ค่าเริ่มต้น 60 วินาที ซึ่งหากไม่เปลี่ยน ค่าเดิมจะตัดการทำงานของ agent ที่ใช้เวลานานกลางคันและทำให้ UI ดูค้างไป ส่วน proxy_buffering off จะส่งผลลัพธ์จากโมเดลไปยังเบราว์เซอร์ทันทีที่ได้รับ แทนที่จะรอจนกว่าการตอบกลับจะเสร็จสิ้น การตั้งค่า nginx reverse proxy ทีละบรรทัด อธิบายส่วนที่เหลือ และ การเลือกใช้ระหว่าง nginx, Caddy และ Traefik ครอบคลุมถึงการทำสิ่งเดียวกันด้วยใบรับรองอัตโนมัติ
ปิดพอร์ต 3080 ที่ firewall ไว้เสมอไม่ว่าคุณจะเลือกใช้ proxy ตัวใด เพื่อให้เส้นทางเดียวที่จะเข้าถึงระบบได้คือผ่านช่องทางที่มีการยืนยันตัวตนเท่านั้น พื้นฐาน ufw firewall ครอบคลุมถึงกฎการตั้งค่าต่างๆ การใช้ basic authentication ผ่าน TLS เป็นเพียงมาตรฐานขั้นต่ำ ไม่ใช่โมเดลความปลอดภัยที่สมบูรณ์แบบ: ใครก็ตามที่ถือรหัสผ่านนั้นก็เท่ากับถือสิทธิ์การเข้าถึง shell บนเซิร์ฟเวอร์ของคุณ ดังนั้นควรเลือกใช้ tunnel หากทำได้
ฉันจะเปลี่ยนพอร์ตที่ dsh web ใช้รับการเชื่อมต่อได้อย่างไร
--port เป็นส่วนของเว็บแอปพลิเคชัน ไม่ใช่ตัว launcher เอกสารประกอบ CLI ได้ให้ตัวอย่างไว้โดยตรงดังนี้:
dsh --profile web --port 8080dsh web เป็นนามแฝงของ --profile web ดังนั้น dsh web --port 8080 จึงเป็นคำสั่งเดียวกัน ตัว launcher จะประมวลผลเฉพาะ flag ของตัวมันเองเท่านั้น และส่งต่อทุกอย่างที่ตามหลังมาให้กับโปรไฟล์ที่ถูกเรียกใช้งาน ดังนั้น flag ของ launcher ต้องอยู่ข้างหน้าเสมอ และ token แรกที่ launcher ไม่รู้จักจะเป็นจุดเริ่มต้นของอาร์กิวเมนต์สำหรับแอปพลิเคชัน ให้วาง --port ไว้หลังชื่อโปรไฟล์เสมอ ห้ามวางไว้ข้างหน้า
ให้อ่าน URL ที่คำสั่งแสดงผลออกมาแทนการคาดเดา เพราะบรรทัดนั้นจะรายงานที่อยู่ที่เซิร์ฟเวอร์ผูกไว้จริง จากนั้นจึงอัปเดตฟิลด์สุดท้ายของ tunnel ของคุณให้ตรงกัน:
ssh -N -L 3080:127.0.0.1:8080 you@your-vpsสำหรับการเปลี่ยนแปลงแบบถาวร พอร์ตจะถูกกำหนดไว้ในการตั้งค่าโปรไฟล์แทนที่จะกำหนดผ่านบรรทัดคำสั่ง โปรไฟล์ web และ headless จะถูกเริ่มต้นใช้งานอัตโนมัติในการเรียกใช้ครั้งแรกจากเทมเพลตที่มาพร้อมกับซอฟต์แวร์ ภายใต้ ~/.dsh หากต้องการดูว่าค่าใดที่มีผลจริงหลังจากรวมเลเยอร์การตั้งค่าทั้งหมดแล้ว ให้ใช้:
dsh --dump-configปลั๊กอินเว็บเซิร์ฟเวอร์เปิดเผย key ออกมาเพียงสองตัวเท่านั้น คือ host และ port การตั้งค่า port เป็น 0 คือการร้องขอพอร์ตว่างจากระบบปฏิบัติการ ซึ่งในเอกสารระบุว่า "ค่าศูนย์เป็นการร้องขอพอร์ตที่ระบบปฏิบัติการกำหนดให้" วิธีนี้รับประกันว่าคุณจะไม่พบปัญหาพอร์ตชนกัน แต่ไม่เหมาะกับการใช้งานร่วมกับ tunnel เพราะหมายเลขพอร์ตจะเปลี่ยนไปทุกครั้งที่รีสตาร์ทเซิร์ฟเวอร์
เหตุใด dsh จึงล้มเหลวด้วยข้อความ address already in use?
เนื่องจากมีกระบวนการอื่นใช้งานที่อยู่และพอร์ตนั้นอยู่แล้ว เคอร์เนลจึงปฏิเสธการ 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 อยู่แล้ว
ตรึงเวอร์ชันไว้ เนื่องจากนี่เป็นรุ่น developer preview
README ระบุไว้อย่างชัดเจนว่า DeepSeek Harness ยังอยู่ในสถานะ developer preview และมีการพัฒนาอย่างรวดเร็ว ซึ่งจะมีการเปลี่ยนแปลงที่ส่งผลต่อความเข้ากันได้ (compatibility-breaking changes)
npx @deepseek-ai/dsh web จะดึงเวอร์ชันล่าสุดที่เผยแพร่มาให้ทุกครั้งที่คุณรันคำสั่ง เซิร์ฟเวอร์ที่คุณไม่ได้แตะต้องมาเป็นสัปดาห์อาจเริ่มการทำงานด้วย CLI ที่ต่างออกไปในการเปิดใช้งานครั้งถัดไป พร้อมด้วย flag ที่เปลี่ยนไป ให้ตรึงเวอร์ชันไว้เพื่อให้การรีสตาร์ทไม่ใช่การอัปเกรด:
npx @deepseek-ai/dsh@0.1.0-rc.7 webณ เดือนสิงหาคม 2026 แพ็กเกจที่เผยแพร่อยู่คือเวอร์ชัน 0.1.0-rc.7 ให้ตรวจสอบว่าการใช้ npx แบบปกติจะดึงเวอร์ชันใดมาก่อนที่คุณจะยอมรับ:
npm view @deepseek-ai/dsh versionFlag ต่างๆ มักมีการย้ายตำแหน่งระหว่างตัวเรียกใช้งาน (launcher) และเว็บแอปพลิเคชันในแต่ละรุ่น preview หาก --port เริ่มทำงานไม่ตรงกับที่อธิบายไว้ในคู่มือนี้ ให้เรียกดูรายการ flag จากตัวแอปพลิเคชันเองแทนการคาดเดา:
dsh --profile web --helpสำหรับการติดตั้ง การตั้งค่า workspace และ model key โปรดดูที่ การติดตั้ง DeepSeek Harness บน VPS สำหรับขั้นตอนการเข้าถึงเพียงอย่างเดียวที่กระชับกว่า การเข้าถึง dsh Web UI บน VPS จะครอบคลุมเรื่องการทำ tunnel โดยไม่ลงรายละเอียดเชิงลึก
FAQ
ทำไมฉันถึงเปิด http://127.0.0.1:3080 ในเบราว์เซอร์บนแล็ปท็อปไม่ได้?
เพราะ 127.0.0.1 หมายถึงเครื่องที่คุณกำลังใช้งานอยู่ Web UI ของ DeepSeek Harness ถูกผูกไว้กับ loopback address ของ VPS ดังนั้นจะมีเพียงกระบวนการที่ทำงานบน VPS เท่านั้นที่เชื่อมต่อได้ แล็ปท็อปของคุณมี loopback แยกต่างหาก และไม่มีบริการใดกำลังฟังพอร์ต 3080 อยู่ที่นั่น ให้ทำ port forwarding ผ่าน SSH ด้วย ssh -N -L 3080:127.0.0.1:3080 you@your-vps จากนั้นจึงโหลด http://127.0.0.1:3080 ในเครื่องของคุณ ค่าในส่วนกลางของอาร์กิวเมนต์ -L จะถูก resolve ที่ฝั่งเซิร์ฟเวอร์ ซึ่งเป็นสิ่งที่ทำให้มันชี้ไปยังตัว harness ได้
การผูก dsh Web UI ไว้ที่ 0.0.0.0 บน VPS สาธารณะปลอดภัยหรือไม่?
ไม่ปลอดภัย Web UI คือส่วนควบคุมสำหรับเอเจนต์ที่รันคำสั่ง shell และแก้ไขไฟล์ในฐานะผู้ใช้ที่รัน dsh และในเวอร์ชัน developer preview นี้ไม่มีหน้าจอเข้าสู่ระบบเลย การผูกไว้กับทุกอินเทอร์เฟซบน public IP หมายความว่าใครก็ตามที่เข้าถึงพอร์ต 3080 ได้จะสามารถรันคำสั่งบนเซิร์ฟเวอร์ของคุณได้ ให้ผูกไว้ที่ 127.0.0.1 เท่านั้น ปิดพอร์ต 3080 ที่ไฟร์วอลล์ และใช้ SSH tunnel, private overlay network หรือ reverse proxy ที่ต้องใช้รหัสผ่านแทน
ฉันจะให้ dsh Web UI ทำงานต่อไปได้อย่างไรหลังจากปิด SSH session?
การรัน npx @deepseek-ai/dsh web ไว้ที่ foreground จะถือเป็น child process ของ login shell ของคุณ ดังนั้นมันจะถูกปิดเมื่อ shell นั้นจบการทำงาน ให้เริ่มการทำงานภายใน session ของ tmux แล้ว detach ออกด้วย Ctrl-b d หรือรันเป็น systemd user service โดยเปิดใช้งาน lingering ไว้ ตัว tunnel และตัว harness นั้นเป็นอิสระต่อกัน คุณสามารถตัดและสร้าง SSH tunnel ใหม่ได้บ่อยเท่าที่ต้องการโดยไม่กระทบต่อ harness ที่กำลังทำงานอยู่ ตราบใดที่ harness นั้นมี parent process ที่ยังทำงานอยู่หลังจากที่คุณออกจากระบบไปแล้ว
ทำไม dsh Web UI ถึงค้างระหว่างการทำงานของเอเจนต์ที่ใช้เวลานานเมื่ออยู่หลัง nginx?
เพราะค่าเริ่มต้นของ proxy_read_timeout ใน nginx คือ 60 วินาที ดังนั้นมันจะปิดการเชื่อมต่อที่ไม่มีการส่งข้อมูลเป็นเวลาหนึ่งนาที ซึ่งขั้นตอนของเอเจนต์ที่ใช้เวลานานมักจะเข้าข่ายนี้ ให้ตั้งค่า proxy_read_timeout 3600s; ในบล็อก location เพิ่ม proxy_buffering off; เพื่อให้ output ส่งไปยังเบราว์เซอร์ทันทีที่ได้รับ และส่ง header Upgrade กับ Connection ด้วย proxy_http_version 1.1; เพื่อให้การทำ WebSocket handshake สำเร็จ หากไม่มี header เหล่านั้น หน้าเว็บจะโหลดขึ้นมาแต่จะไม่ได้รับข้อมูลอัปเดตใดๆ