Qué significa http://127.0.0.1:3080 en dsh web
dsh muestra http://127.0.0.1:3080 porque la Web UI solo escucha en localhost. Acceda con un túnel SSH y vea por qué publicar el puerto 3080 es inseguro.
Qué significa dsh web: http://127.0.0.1:3080
Cuando inicia el perfil web de DeepSeek Harness en un VPS, muestra dos líneas y espera:
dsh web: http://127.0.0.1:3080
Ready.127.0.0.1 es la dirección de loopback. Es la dirección que una máquina usa para comunicarse consigo misma. Un socket enlazado a 127.0.0.1 acepta conexiones de procesos de esa misma máquina y de ningún otro lugar. Por tanto, esa línea indica dos cosas a la vez: dónde está escuchando la interfaz web y quién puede acceder a ella. Sólo puede acceder la máquina en la que se ejecuta dsh.
Por eso la URL no hace nada cuando la pega en el navegador de su portátil. El 127.0.0.1 de su portátil corresponde a su propio portátil. Harness está escuchando en el 127.0.0.1 del VPS, que es otra máquina con otra pila de loopback. No hay ningún fallo. Debe transportar la conexión entre ambas máquinas.
El README oficial indica claramente el valor predeterminado: "El comando inicia la interfaz web, disponible en http://127.0.0.1:3080 de forma predeterminada." La dirección de enlace procede del plugin de host del servidor web, @deepseek-ai/dsh-host-webserver, cuya clave host está documentada como "Host de escucha; los dos valores admitidos son loopback y todas las interfaces". Obtendrá loopback si no cambia esta configuración. Si los puertos son nuevos para usted, cómo funcionan los puertos en Linux explica el modelo de dirección y puerto en el que se basa todo esto.
Por qué la interfaz web sólo se enlaza a localhost
dsh es un entorno de ejecución del agente, es decir, el programa que envuelve al modelo: controla el bucle, las llamadas a herramientas y los permisos con los que se ejecutan esas llamadas. La pestaña del navegador es una superficie de control para un proceso que ejecuta comandos de shell, lee y escribe archivos en el directorio de trabajo que eligió y consume su clave de API del modelo. Cualquiera que pueda cargar esa página puede hacer todo eso como el usuario que ejecuta dsh. La red tampoco es la única vía de acceso a ese alcance: un plugin que instale se ejecuta dentro del mismo proceso y con los mismos permisos. Por eso, revisar un plugin de dsh antes de instalarlo requiere el mismo cuidado que decidir en qué dirección escucha el servidor.
Por tanto, el puerto 3080 no es un panel de sólo lectura. Cargar esa página permite ejecutar comandos en el servidor.
Abra la interfaz web y accederá directamente a la lista de sesiones. No aparece ninguna solicitud de inicio de sesión porque la versión preliminar para desarrolladores no incluye cuentas de usuario ni autenticación remota. En loopback, esto es coherente: el sistema operativo controla el acceso y sólo pueden conectarse los procesos locales. Enlace el mismo servidor a 0.0.0.0 en un VPS con una IP pública y esa misma página responderá a todo Internet, sin ningún componente delante. Los escáneres automatizados exploran continuamente los puertos poco habituales, así que debe considerar descubierto cualquier puerto 3080 publicado.
No abra el puerto 3080 en el firewall ni configurehostdel servidor web con0.0.0.0en un VPS público. Esa combinación entrega la ejecución de comandos del servidor a quien se conecte primero.
El mismo razonamiento se aplica a cualquier entorno de ejecución de agentes que instale en un servidor. Por eso, ejecutar un agente de programación de forma segura en un VPS parte de la misma regla: el puerto de control del agente permanece privado y un componente de confianza le permite acceder a él.
¿Cómo abro la interfaz web de dsh desde mi portátil?
Hay tres opciones correctas, y todas mantienen el harness enlazado a loopback.
- Un túnel SSH. No se abre ningún servicio nuevo en la interfaz pública y ya dispone de las credenciales. Esta es la opción que debe usar.
- Una red overlay privada, para que la interfaz sea accesible desde sus propios dispositivos y permanezca invisible para los demás.
- Un reverse proxy que termine TLS (seguridad de la capa de transporte) y solicite una contraseña antes de reenviar cualquier petición.
La diferencia entre estas opciones es el mecanismo que conecta el navegador con loopback. Ninguna debe implicar mover el harness fuera de loopback.
Acceda mediante un túnel SSH
Ejecute esto en su portátil, no en el VPS:
ssh -N -L 3080:127.0.0.1:3080 you@your-vpsDéjelo en ejecución y abra http://127.0.0.1:3080 en el navegador local. La interfaz web se cargará.
El argumento -L contiene tres campos separados por dos puntos. El primero es el puerto que se abrirá en el portátil. El segundo y el tercero son la dirección y el puerto a los que se reenviará cada conexión. El detalle importante es el siguiente: 127.0.0.1 del campo central lo resuelve el servidor SSH del VPS, después de que el tráfico ya haya llegado allí. Hace referencia al loopback del VPS, no al del portátil. Esa es exactamente la dirección que mostró dsh, por eso el túnel funciona cuando una conexión directa desde el navegador no funciona.
-N indica a SSH que no ejecute ningún comando remoto. Así se obtiene un reenviador sin shell. Para crear un túnel en segundo plano que informe de los errores en lugar de fallar silenciosamente:
ssh -N -f -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -L 3080:127.0.0.1:3080 you@your-vps-f lo envía a segundo plano después de la autenticación. ExitOnForwardFailure=yes es más importante de lo que parece: sin esta opción, SSH se conecta correctamente aunque no haya podido configurar el reenvío. Así se obtiene una sesión activa y un túnel inactivo sin ninguna advertencia. ServerAliveInterval=30 envía un keepalive cada 30 segundos para que un túnel inactivo sobreviva a los tiempos de espera de NAT (traducción de direcciones de red) de los routers de cafeterías y hoteles.
Qué debería ver
En el VPS, confirme qué proceso está escuchando realmente:
ss -ltnp | grep 3080Un resultado correcto muestra la dirección de loopback:
LISTEN 0 511 127.0.0.1:3080 0.0.0.0:* users:(("node",pid=1042,fd=21))Si la columna de dirección local muestra 0.0.0.0:3080 en su lugar, la interfaz web está disponible en todas las interfaces, incluida la pública. Deténgala y corrija la dirección de bind antes de hacer cualquier otra cosa. Si ss muestra el socket pero deja vacío el campo users:, ejecútelo con sudo, porque de lo contrario se oculta el nombre del proceso cuando el socket pertenece a otro usuario.
Cuando el túnel no se inicia
SSH muestra esto y termina:
bind [127.0.0.1]:3080: Address already in use
channel_setup_fwd_listener_tcpip: cannot listen to port: 3080El problema está en el portátil, no en el servidor. Algo local ya está usando el puerto 3080, normalmente un túnel anterior que olvidó cerrar. Elija otro puerto local libre:
ssh -N -L 3081:127.0.0.1:3080 you@your-vpsSólo cambió el primer campo, así que ahora debe abrir http://127.0.0.1:3081 en el navegador, mientras el harness sigue escuchando en 3080. Los dos números no tienen que coincidir.
Si el túnel se inicia pero el navegador informa de una conexión rechazada o de una respuesta vacía, el tráfico llegó al VPS, pero no encontró nada en el extremo remoto. Puede que dsh haya terminado o que se haya asociado a otro puerto. Compruébelo con ss -ltnp | grep 3080 en el servidor.
Hay otro problema frecuente. Un npx @deepseek-ai/dsh web en primer plano termina cuando se cierra su shell, por lo que el harness se detiene en cuanto cierra la sesión. Inícielo dentro de tmux o mediante un servicio de usuario de systemd. Es el mismo problema que se resuelve en mantener un agente de programación en ejecución en un VPS. Mientras trabaja en la configuración de SSH, conviene hacer primero reforzar la seguridad de SSH en su VPS, porque el túnel hace que su inicio de sesión SSH sea la única puerta de acceso al agente.
Acceso mediante una red overlay privada
Una red overlay asigna a tu VPS y a tu portátil direcciones de una red privada a la que sólo se conectan tus dispositivos. Tailscale es la opción habitual, y su comando serve encaja exactamente en este caso: tailscaled se ejecuta en el VPS y se conecta al propio localhost:3080, de modo que el harness sigue usando loopback y no tienes que cambiar la configuración de dsh.
tailscale serve --bg localhost:3080
tailscale serve statusLa interfaz queda accesible en el nombre de tu equipo dentro de tu tailnet, mediante HTTPS y sin abrir ningún puerto en la interfaz pública. Para ello, debes habilitar certificados HTTPS para tu tailnet; de lo contrario, serve no tendrá ningún certificado que presentar. Para desactivarlo, repite el comando con off:
tailscale serve --https=443 offUsa serve, nunca funnel. Funnel publica el mismo destino en Internet, lo que te devuelve a un runtime de agente sin autenticación en un puerto abierto. Los dos comandos son casi idénticos, pero hacen lo contrario. Lee la diferencia entre Tailscale Serve y Funnel antes de ejecutar cualquiera de ellos. Tailscale como red privada explica la configuración.
Acceda a través de un proxy inverso que compruebe una contraseña
Esta es la opción que realmente publica un puerto en Internet, por lo que la autenticación es lo único que separa a un desconocido de la ejecución de comandos en su servidor. Elíjala cuando varias personas necesiten la interfaz y no sea práctico configurar un túnel para cada una.
El harness sigue en 127.0.0.1:3080. nginx se ejecuta en el mismo equipo, por lo que puede acceder a loopback, y escucha en 443 con un certificado y un archivo de contraseñas.
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;
}
}Cree el archivo de contraseñas y recargue la configuración:
sudo apt install -y apache2-utils
sudo htpasswd -c /etc/nginx/dsh.htpasswd you
sudo nginx -t && sudo systemctl reload nginxnginx -t debería mostrar syntax is ok seguido de test is successful. Una recarga con un archivo incorrecto falla y mantiene activa la configuración anterior, por lo que debe leer el error en lugar de reiniciar a ciegas.
Tres de esas líneas del proxy no son decorativas. Las cabeceras Upgrade y Connection permiten completar el handshake de WebSocket. Sin ellas, la página se carga, pero nunca se actualiza. proxy_read_timeout 3600s reemplaza el valor predeterminado de 60 segundos. De lo contrario, interrumpe una ejecución larga del agente a mitad de la respuesta y hace que la interfaz parezca bloqueada. proxy_buffering off envía la salida del modelo al navegador a medida que llega, en lugar de retenerla hasta que se complete la respuesta. Una configuración de proxy inverso de nginx, línea por línea explica el resto, y cómo elegir entre nginx, Caddy y Traefik explica cómo hacer lo mismo con certificados automáticos.
Mantenga 3080 cerrado en el firewall independientemente del proxy que elija, de modo que la única vía de acceso sea el proxy autenticado. Conceptos básicos del firewall ufw explica las reglas. La autenticación básica mediante TLS es un nivel mínimo, no un modelo de seguridad completo: quien tenga esa contraseña tendrá acceso a un shell en su servidor. Siempre que sea posible, prefiera el túnel.
¿Cómo cambio el puerto en el que escucha dsh web?
--port pertenece a la aplicación web, no al launcher. La documentación de la CLI muestra directamente el ejemplo:
dsh --profile web --port 8080dsh web es un alias de --profile web, por lo que dsh web --port 8080 es el mismo comando. El launcher analiza sólo sus propias opciones y pasa todo lo que aparece después al perfil iniciado. Por tanto, las opciones del launcher van primero, y el primer token que el launcher no reconoce inicia los argumentos de la aplicación. Coloque --port después del perfil, nunca antes.
Lea la URL que imprime el comando en lugar de darla por supuesta, porque esa línea muestra la dirección a la que el servidor se ha asociado realmente. Después, actualice el último campo del túnel para que coincida:
ssh -N -L 3080:127.0.0.1:8080 you@your-vpsPara aplicar el cambio de forma permanente, el puerto se configura en el perfil, no en la línea de comandos. Los perfiles web y headless se inicializan automáticamente la primera vez que se usan a partir de las plantillas incluidas, en ~/.dsh. Ese mismo directorio contiene la configuración de la API key y del endpoint del modelo, por lo que configurar las claves, los modelos y los endpoints de dsh es la lectura complementaria si ya va a editar estos archivos. Para comprobar qué configuración está activa después de combinar todas las capas:
dsh --dump-configEl plugin del servidor web expone exactamente dos claves: host y port. Establecer port en 0 solicita al sistema operativo un puerto libre. La documentación indica que «cero solicita un puerto asignado por el sistema operativo». Esto evita los conflictos de puerto, pero no es adecuado para un túnel porque el número cambia en cada reinicio.
¿Por qué dsh falla con el error «address already in use»?
Otro proceso ya usa esa dirección y ese puerto, por lo que el kernel rechaza el segundo bind. Node lo muestra así:
Error: listen EADDRINUSE: address already in use 127.0.0.1:3080Identifique qué proceso usa la dirección antes de cambiar nada:
sudo ss -ltnp | grep 3080El campo users:(("node",pid=1042,fd=21)) indica el proceso y su PID. Lo habitual es que se trate de una instancia anterior de dsh que creía detenida y que todavía sigue activa en una ventana de tmux separada. Deténgala con kill 1042 o inicie la nueva instancia en otro puerto. Tenga en cuenta que 127.0.0.1:3080 y 0.0.0.0:3080 también entran en conflicto, porque enlazar todas las interfaces ya incluye la interfaz de loopback.
Fije la versión porque se trata de una vista previa para desarrolladores
El README lo indica claramente: DeepSeek Harness está en vista previa para desarrolladores, evoluciona con rapidez y habrá cambios incompatibles. Si ese ritmo es el motivo de sus dudas, cómo se compara dsh con Claude Code y Omnigent lo contrasta con dos harnesses que se encuentran en puntos distintos de la misma evolución.
npx @deepseek-ai/dsh web se resuelve siempre en la versión publicada más reciente cada vez que lo ejecuta. Un servidor que no ha tocado durante una semana puede iniciar un CLI diferente la próxima vez, con flags distintos. Fije la versión para que un reinicio no sea una actualización:
npx @deepseek-ai/dsh@0.1.0-rc.7 webEn agosto de 2026, el paquete publicado es la versión 0.1.0-rc.7. Compruebe qué instalaría un npx sin versión fijada antes de aceptarlo:
npm view @deepseek-ai/dsh versionSi la versión fijada no se instala o npx sigue iniciando la compilación antigua después de fijar una nueva, los errores de instalación y versión que produce explica cómo borrar la caché de npx y comprobar qué npm incluye su Node.
Los flags cambian entre el launcher y la aplicación web en las distintas versiones de vista previa. Si --port deja de comportarse como se describe en esta guía, solicite a la aplicación su propia lista de flags en lugar de intentar adivinarlos:
dsh --profile web --helpPara la instalación, la configuración del workspace y la clave del modelo, consulte instalar DeepSeek Harness en un VPS. Para una guía más breve sólo del paso de acceso, acceder a la interfaz web de dsh en un VPS explica el túnel sin el razonamiento.
FAQ
¿Por qué no puedo abrir http://127.0.0.1:3080 en el navegador de mi portátil?
Porque 127.0.0.1 identifica el equipo desde el que escribe. La interfaz web de DeepSeek Harness está vinculada a la dirección de loopback del VPS, por lo que sólo los procesos del VPS pueden conectarse a ella. El portátil tiene su propio loopback independiente y allí no hay ningún proceso escuchando en el puerto 3080. Reenvíe el puerto mediante SSH con ssh -N -L 3080:127.0.0.1:3080 you@your-vps y cargue http://127.0.0.1:3080 localmente. El campo intermedio del argumento -L se resuelve en el servidor, por lo que apunta al harness.
¿Es seguro vincular la interfaz web de dsh a 0.0.0.0 en un VPS público?
No. La interfaz web controla un agente que ejecuta comandos de shell y modifica archivos con el usuario que ejecuta dsh, y la vista previa para desarrolladores no muestra ninguna pantalla de inicio de sesión. Vincularla a todas las interfaces de una IP pública significa que cualquiera que acceda al puerto 3080 podrá ejecutar comandos en el servidor. Mantenga la vinculación en 127.0.0.1, mantenga cerrado el puerto 3080 en el firewall y use un túnel SSH, una red superpuesta privada o un reverse proxy que requiera contraseña.
¿Cómo puedo mantener la interfaz web de dsh en ejecución después de cerrar la sesión SSH?
Un npx @deepseek-ai/dsh web en primer plano es un proceso hijo del shell de inicio de sesión, por lo que termina cuando ese shell se cierra. Inícielo dentro de una sesión tmux y sepárese con Ctrl-b d, o ejecútelo como un servicio de usuario de systemd con lingering habilitado. El túnel y el harness son independientes: puede cerrar y reconstruir el túnel SSH tantas veces como quiera sin afectar al harness en ejecución, siempre que el propio harness tenga un proceso padre que sobreviva a su inicio de sesión.
¿Por qué se bloquea la interfaz web de dsh a mitad de una ejecución larga del agente detrás de nginx?
Porque el valor predeterminado de proxy_read_timeout en nginx es de 60 segundos. nginx cierra una conexión que no produce datos durante un minuto, algo habitual durante un paso largo del agente. Configure proxy_read_timeout 3600s; en el bloque location. Añada proxy_buffering off; para que la salida se transmita al navegador a medida que llega y envíe las cabeceras Upgrade y Connection mediante proxy_http_version 1.1; para que el handshake de WebSocket se complete correctamente. Sin esas cabeceras, la página se carga, pero nunca recibe actualizaciones.