SSD Nodes Learn Hosting plans →
Guides Matt ConnorPar Matt Connor · Mis à jour le 2026-08-26

dsh : que signifie http://127.0.0.1:3080 ?

dsh affiche http://127.0.0.1:3080 car l’interface Web écoute seulement sur localhost. Accédez-y avec un tunnel SSH et évitez d’exposer le port 3080.

Signification de dsh web: http://127.0.0.1:3080

Lorsque vous démarrez le profil Web de DeepSeek Harness sur un VPS, deux lignes s’affichent, puis le processus attend :

dsh web: http://127.0.0.1:3080
Ready.

127.0.0.1 est l’adresse loopback. C’est l’adresse qu’une machine utilise pour communiquer avec elle-même. Un socket lié à 127.0.0.1 accepte les connexions des processus présents sur cette même machine, et de nulle part ailleurs. Cette ligne vous indique donc deux choses à la fois : l’adresse sur laquelle l’interface Web écoute et les machines autorisées à y accéder. Seule la machine sur laquelle dsh s’exécute peut y accéder.

C’est pourquoi l’URL ne fait rien lorsque vous la collez dans le navigateur de votre ordinateur portable. Le 127.0.0.1 de votre ordinateur portable est celui de votre ordinateur portable. Le harness écoute sur le 127.0.0.1 du VPS, qui est une autre machine avec une autre pile loopback. Rien n’est défectueux. Vous devez faire transiter la connexion.

Le README officiel indique clairement la valeur par défaut : « La commande démarre l’interface Web, servie par http://127.0.0.1:3080 par défaut. » L’adresse d’écoute provient du plugin d’hôte du webserver, @deepseek-ai/dsh-host-webserver, dont la clé host est documentée ainsi : « Hôte d’écoute ; les deux valeurs prises en charge sont loopback et all-interfaces ». Vous obtenez loopback tant que vous ne modifiez pas cette valeur. Si les ports sont nouveaux pour vous, fonctionnement des ports sous Linux présente le modèle adresse-plus-port sur lequel repose tout ceci.

Pourquoi l’interface Web est liée uniquement à localhost

dsh est un agent harness, c’est-à-dire le programme qui encapsule le modèle : il gère la boucle d’exécution, les appels aux outils et les permissions utilisées par ces appels. L’onglet du navigateur sert d’interface de contrôle à un processus qui exécute des commandes shell, lit et écrit des fichiers dans le répertoire de travail que vous avez choisi et utilise votre clé d’API du modèle. Toute personne capable de charger cette page peut effectuer ces opérations avec les droits de l’utilisateur qui exécute dsh. Le réseau n’est d’ailleurs pas le seul moyen d’accéder à ces fonctions : un plugin que vous installez s’exécute dans le même processus avec les mêmes permissions. C’est pourquoi vérifier un plugin dsh avant de l’installer demande la même rigueur que le choix de ce que le serveur doit écouter.

Le port 3080 n’est donc pas un dashboard en lecture seule. Charger cette page permet d’exécuter des commandes sur le serveur.

Ouvrez l’interface Web pour accéder directement à la liste des sessions. Aucun écran de connexion ne s’affiche, car la preview développeur ne fournit ni comptes utilisateur ni authentification distante. Sur loopback, ce fonctionnement est cohérent : le système d’exploitation assure le contrôle d’accès et seuls les processus locaux peuvent se connecter. Si vous liez le même serveur à 0.0.0.0 sur un VPS doté d’une adresse IP publique, cette même page répond à l’ensemble d’Internet, sans aucune protection en amont. Les scanners automatisés balaient en permanence les ports peu courants. Considérez donc qu’un port 3080 publié est immédiatement découvert.

N’ouvrez pas le port 3080 dans votre firewall et ne définissez pas host du webserver sur 0.0.0.0 sur un VPS public. Cette combinaison donne l’exécution de commandes sur votre serveur à la première personne qui se connecte.

Le même raisonnement s’applique à tout runtime d’agent que vous installez sur un serveur. C’est pourquoi exécuter un agent de code en toute sécurité sur un VPS commence par la même règle : le port de contrôle de l’agent reste privé et un composant de confiance vous permet d’y accéder.

Comment ouvrir l’interface Web de dsh depuis mon ordinateur portable ?

Il existe trois méthodes fiables, et dans tous les cas le harness reste lié à l’interface loopback.

  • Un tunnel SSH. Aucun nouveau service n’écoute sur l’interface publique, et vous disposez déjà des identifiants. C’est la méthode à utiliser.
  • Un réseau overlay privé, afin que l’interface soit accessible depuis vos propres appareils et invisible pour les autres.
  • Un reverse proxy avec terminaison TLS (Transport Layer Security) qui exige un mot de passe avant de transmettre quoi que ce soit.

La différence tient au mécanisme qui achemine votre navigateur vers l’interface loopback. Dans aucun cas vous ne devez déplacer le harness hors de l’interface loopback.

Accéder au service avec un tunnel SSH

Exécutez cette commande sur votre ordinateur portable, pas sur le VPS :

ssh -N -L 3080:127.0.0.1:3080 you@your-vps

Laissez-la s’exécuter, puis ouvrez http://127.0.0.1:3080 dans le navigateur local. L’interface Web se charge.

L’argument -L contient trois champs séparés par des deux-points. Le premier indique le port à ouvrir sur votre ordinateur portable. Les deuxième et troisième indiquent l’adresse et le port vers lesquels chaque connexion doit être redirigée. Le point important est le suivant : 127.0.0.1, dans le champ du milieu, est résolu par le serveur SSH sur le VPS, après l’arrivée de votre trafic sur celui-ci. Il désigne la loopback du VPS, et non la vôtre. C’est précisément l’adresse affichée par dsh, ce qui explique pourquoi le tunnel fonctionne alors qu’une connexion directe depuis le navigateur échoue.

-N indique à SSH de ne pas exécuter de commande distante. Vous obtenez donc un redirecteur, sans shell. Pour exécuter un tunnel en arrière-plan et afficher clairement les erreurs :

ssh -N -f -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -L 3080:127.0.0.1:3080 you@your-vps

-f le place en arrière-plan après l’authentification. ExitOnForwardFailure=yes est plus important qu’il n’y paraît : sans cette option, SSH se connecte correctement même si la redirection n’a pas pu être configurée. Vous obtenez alors une session fonctionnelle, mais un tunnel inactif, sans avertissement. ServerAliveInterval=30 envoie un keepalive toutes les 30 secondes afin qu’un tunnel inactif survive aux timeouts de NAT (network address translation) des routeurs de cafés et d’hôtels.

Ce que vous devez voir

Sur le VPS, vérifiez ce qui est réellement en écoute :

ss -ltnp | grep 3080

Un résultat correct indique l’adresse loopback :

LISTEN 0  511  127.0.0.1:3080  0.0.0.0:*  users:(("node",pid=1042,fd=21))

Si la colonne de l’adresse locale contient 0.0.0.0:3080 à la place, l’interface Web écoute sur toutes les interfaces, y compris l’interface publique. Arrêtez-la et corrigez l’adresse d’écoute avant toute autre opération. Si ss affiche le socket, mais laisse le champ users: vide, exécutez-le avec sudo, car le nom du processus associé à un socket appartenant à un autre utilisateur est sinon masqué.

Lorsque le tunnel refuse de démarrer

SSH affiche ce message, puis se termine :

bind [127.0.0.1]:3080: Address already in use
channel_setup_fwd_listener_tcpip: cannot listen to port: 3080

Le problème vient de votre ordinateur portable, pas du serveur. Un processus local utilise déjà le port 3080, souvent un ancien tunnel que vous avez oublié. Choisissez plutôt un port local libre :

ssh -N -L 3081:127.0.0.1:3080 you@your-vps

Seul le premier champ a changé. Vous ouvrez donc maintenant http://127.0.0.1:3081 dans le navigateur, tandis que le harness continue d’écouter sur le port 3080. Les deux numéros ne doivent pas nécessairement être identiques.

Si le tunnel démarre, mais que le navigateur signale une connexion refusée ou une réponse vide, le trafic a bien atteint le VPS, mais rien n’écoutait à l’autre extrémité. Soit dsh s’est terminé, soit il écoute sur un autre port. Vérifiez avec ss -ltnp | grep 3080 sur le serveur.

Un autre point pose souvent problème. Un npx @deepseek-ai/dsh web exécuté au premier plan se termine lorsque son shell se ferme. Le harness s’arrête donc dès que vous vous déconnectez. Démarrez-le dans tmux ou avec un service systemd utilisateur. Cela résout le même problème que celui décrit dans laisser un agent de programmation s’exécuter sur un VPS. Pendant que vous configurez la partie SSH, pensez d’abord à renforcer la sécurité de SSH sur votre VPS, car le tunnel fait de votre connexion SSH le seul accès à l’agent.

Y accéder via un réseau overlay privé

Un réseau overlay attribue à votre VPS et à votre ordinateur portable des adresses sur un réseau privé auquel seuls vos appareils peuvent se connecter. Tailscale est le choix courant, et sa commande serve convient exactement à ce cas : tailscaled s’exécute sur le VPS et se connecte lui-même à localhost:3080. Le harness reste ainsi lié à loopback, et vous ne modifiez rien à la configuration de dsh.

tailscale serve --bg localhost:3080
tailscale serve status

L’interface est alors accessible via le nom de votre machine dans votre tailnet, en HTTPS, sans aucun port ouvert sur l’interface publique. Les certificats HTTPS doivent être activés pour votre tailnet ; sinon, serve n’a aucun certificat à présenter. Pour désactiver ce mode, répétez la commande avec off :

tailscale serve --https=443 off

Utilisez serve, jamais funnel. Funnel publie la même cible sur Internet, ce qui vous ramène à un agent non authentifié sur un port ouvert. Les deux commandes se ressemblent presque, mais leur effet est opposé. Lisez donc la différence entre Tailscale Serve et Funnel avant d’exécuter l’une ou l’autre. Tailscale comme réseau privé décrit la configuration elle-même.

Accédez-y via un reverse proxy qui vérifie un mot de passe

C’est l’option qui publie réellement un port sur Internet. L’authentification est donc la seule protection entre un inconnu et l’exécution de commandes sur votre serveur. Choisissez cette méthode lorsque plusieurs personnes ont besoin de l’interface et qu’un tunnel par personne n’est pas pratique.

Le harness reste sur 127.0.0.1:3080. nginx s’exécute sur le même serveur, peut donc accéder à loopback, et écoute sur 443 avec un certificat et un fichier de mots de passe.

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;
    }
}

Créez le fichier de mots de passe, puis rechargez la configuration :

sudo apt install -y apache2-utils
sudo htpasswd -c /etc/nginx/dsh.htpasswd you
sudo nginx -t && sudo systemctl reload nginx

nginx -t doit afficher syntax is ok, suivi de test is successful. Le rechargement échoue si le fichier est incorrect et conserve la configuration active. Lisez donc l’erreur au lieu de redémarrer sans vérifier.

Trois de ces lignes du proxy sont indispensables. Les en-têtes Upgrade et Connection permettent la négociation WebSocket. Sans eux, la page se charge mais ne se met jamais à jour. proxy_read_timeout 3600s remplace la valeur par défaut de 60 secondes. Sans ce réglage, une longue exécution de l’agent est interrompue au milieu de la réponse et l’interface semble bloquée. proxy_buffering off envoie la sortie du modèle au navigateur au fur et à mesure, au lieu d’attendre la fin de la réponse. Configuration d’un reverse proxy nginx, ligne par ligne explique le reste, et choisir entre nginx, Caddy et Traefik explique comment faire la même chose avec des certificats automatiques.

Laissez 3080 fermé dans le firewall, quel que soit le proxy choisi, afin que le seul chemin d’accès passe par celui qui est authentifié. notions de base sur le firewall ufw explique les règles. L’authentification de base sur TLS constitue un niveau minimal de protection, pas un modèle de sécurité complet : quiconque possède ce mot de passe dispose d’un shell sur votre serveur. Préférez le tunnel lorsque c’est possible.

Comment modifier le port sur lequel l’interface web de dsh écoute ?

--port appartient à l’application web, pas au launcher. La documentation de la CLI donne directement l’exemple :

dsh --profile web --port 8080

dsh web est un alias de --profile web. dsh web --port 8080 correspond donc à la même commande. Le launcher n’analyse que ses propres options, puis transmet tous les arguments suivants au profil démarré. Les options du launcher doivent donc apparaître en premier. Le premier token que le launcher ne reconnaît pas marque le début des arguments de l’application. Placez --port après le profil, jamais avant.

Lisez l’URL affichée par la commande au lieu de la supposer, car cette ligne indique l’adresse réellement utilisée par le serveur. Modifiez ensuite le dernier champ de votre tunnel pour utiliser cette adresse :

ssh -N -L 3080:127.0.0.1:8080 you@your-vps

Pour appliquer le changement de manière permanente, définissez le port dans la configuration du profil plutôt que sur la ligne de commande. Les profils web et headless s’initialisent automatiquement lors de leur première utilisation à partir des modèles fournis, dans ~/.dsh. Ce même répertoire contient les paramètres de votre clé API et de votre endpoint de modèle. Configurer les clés, modèles et endpoints de dsh est donc la lecture complémentaire à consulter pendant que vous modifiez ces fichiers. Pour voir la configuration réellement appliquée après la fusion de toutes les couches :

dsh --dump-config

Le plugin webserver expose exactement deux clés : host et port. Définir port sur 0 demande au système d’exploitation de choisir un port libre. La documentation précise que « zero requests an OS-assigned port ». Cela garantit l’absence de conflit, mais convient mal à un tunnel, car le numéro change à chaque redémarrage.

Pourquoi dsh échoue-t-il avec l’erreur « address already in use » ?

Un autre processus utilise déjà cette adresse et ce port. Le kernel refuse donc le second bind. Node affiche généralement le message suivant :

Error: listen EADDRINUSE: address already in use 127.0.0.1:3080

Identifiez le processus concerné avant de modifier quoi que ce soit :

sudo ss -ltnp | grep 3080

Le champ users:(("node",pid=1042,fd=21)) indique le processus et son PID. Il s’agit généralement d’une ancienne instance de dsh que vous pensiez avoir arrêtée. Elle est souvent encore active dans une fenêtre tmux détachée. Arrêtez-la avec kill 1042, ou démarrez la nouvelle instance sur un autre port. Notez que 127.0.0.1:3080 et 0.0.0.0:3080 entrent également en conflit, car le bind sur toutes les interfaces inclut déjà loopback.

Figez la version, car il s’agit d’une préversion destinée aux développeurs

Le README est clair : DeepSeek Harness est en préversion destinée aux développeurs et évolue rapidement. Des changements incompatibles sont donc à prévoir. Si ce rythme vous fait hésiter, voici comment dsh se compare à Claude Code et Omnigent, deux autres harnesses qui se trouvent à des étapes différentes de la même évolution.

npx @deepseek-ai/dsh web résout la version publiée la plus récente à chaque exécution. Un serveur que vous n’avez pas touché depuis une semaine peut donc lancer un autre CLI au redémarrage, avec des flags différents. Figez la version afin qu’un redémarrage ne déclenche pas une mise à niveau :

npx @deepseek-ai/dsh@0.1.0-rc.7 web

En août 2026, le package publié est la version 0.1.0-rc.7. Vérifiez ce qu’un npx sans version explicite installerait avant de l’accepter :

npm view @deepseek-ai/dsh version

Si la version figée refuse de s’installer, ou si npx continue de lancer l’ancienne build après que vous en avez figé une nouvelle, ces erreurs d’installation et de version expliquent comment vider le cache npx et vérifier quel npm est fourni avec votre installation de Node.

Les flags sont déplacés entre le launcher et l’application web au fil des versions de préversion. Si --port ne se comporte plus comme décrit dans ce guide, demandez à l’application la liste de ses propres flags au lieu de deviner :

dsh --profile web --help

Pour l’installation, la configuration du workspace et la clé du modèle, consultez installer DeepSeek Harness sur un VPS. Pour suivre uniquement la procédure d’accès, plus courte, accéder à l’interface Web de dsh sur un VPS explique le tunnel sans le raisonnement.

FAQ

Pourquoi ne puis-je pas ouvrir http://127.0.0.1:3080 dans le navigateur de mon ordinateur portable ?

Parce que 127.0.0.1 désigne la machine sur laquelle vous saisissez les commandes. L’interface Web de DeepSeek Harness est liée à l’adresse loopback du VPS. Seuls les processus du VPS peuvent donc s’y connecter. Votre ordinateur portable possède sa propre interface loopback, et aucun processus n’y écoute sur le port 3080. Transférez le port via SSH avec ssh -N -L 3080:127.0.0.1:3080 you@your-vps, puis ouvrez http://127.0.0.1:3080 en local. Le champ central de l’argument -L est résolu côté serveur. C’est ce qui le fait pointer vers le harness.

Est-il sûr de lier l’interface Web de dsh à 0.0.0.0 sur un VPS public ?

Non. L’interface Web contrôle un agent qui exécute des commandes shell et modifie des fichiers avec les droits de l’utilisateur qui exécute dsh. De plus, la version d’aperçu destinée aux développeurs n’affiche aucun écran de connexion. Une liaison à toutes les interfaces sur une adresse IP publique permet à toute personne pouvant atteindre le port 3080 d’exécuter des commandes sur votre serveur. Conservez la liaison sur 127.0.0.1, bloquez le port 3080 dans le pare-feu et utilisez un tunnel SSH, un réseau overlay privé ou un reverse proxy qui exige un mot de passe.

Comment maintenir l’interface Web de dsh après la fermeture de ma session SSH ?

Un npx @deepseek-ai/dsh web exécuté au premier plan est un processus enfant de votre shell de connexion. Il est donc tué lorsque ce shell se termine. Lancez-le dans une session tmux, puis détachez-la avec Ctrl-b d. Vous pouvez aussi l’exécuter comme service systemd utilisateur avec le lingering activé. Le tunnel et le harness sont indépendants : vous pouvez fermer et recréer le tunnel SSH aussi souvent que nécessaire sans toucher au harness en cours d’exécution, à condition que le harness lui-même ait un processus parent qui reste actif après votre déconnexion.

Pourquoi l’interface Web de dsh se fige-t-elle au milieu d’une longue exécution de l’agent derrière nginx ?

Parce que la valeur par défaut de proxy_read_timeout dans nginx est de 60 secondes. nginx ferme donc une connexion qui ne produit aucune donnée pendant une minute, ce qui arrive facilement pendant une longue étape de l’agent. Définissez proxy_read_timeout 3600s; dans le bloc location. Ajoutez proxy_buffering off; pour transmettre la sortie au navigateur dès qu’elle arrive, puis transmettez les en-têtes Upgrade et Connection avec proxy_http_version 1.1; afin que la négociation WebSocket réussisse. Sans ces en-têtes, la page se charge, mais ne reçoit aucune mise à jour.