SSD Nodes Learn 🎉 VPS dès $5.50/mois
Guides Matt ConnorPar Matt Connor · Mis à jour le 2026-08-21

dsh web : 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.

Ce que signifie dsh web: http://127.0.0.1:3080

Lorsque vous démarrez le profil web DeepSeek Harness sur un VPS, il affiche deux lignes, puis attend :

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

127.0.0.1 est l’adresse de bouclage. 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 exécutés sur cette même machine, et d’aucune autre. Cette ligne vous indique donc deux choses à la fois : où l’interface web est en écoute et qui peut y accéder. Seule la machine sur laquelle dsh est exécuté peut y accéder.

C’est pourquoi l’URL ne fait rien lorsque vous la copiez dans le navigateur de votre ordinateur portable. Le 127.0.0.1 de votre ordinateur portable est celui de votre ordinateur portable. Le harness est en écoute sur le 127.0.0.1 du VPS, qui est une autre machine avec une autre pile de bouclage. 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 défaut à http://127.0.0.1:3080. » L’adresse d’écoute provient du plugin d’hôte du serveur web, @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, sauf si vous modifiez cette valeur. Si les ports sont nouveaux pour vous, comment fonctionnent les ports sous Linux explique le modèle adresse-plus-port sur lequel repose tout cela.

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

dsh est un agent harness. 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 consomme votre clé d’API du modèle. Toute personne capable de charger cette page peut effectuer ces opérations avec les privilèges de l’utilisateur qui exécute dsh.

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

Ouvrez l’interface Web et vous arrivez directement dans la liste des sessions. Aucun formulaire de connexion ne s’affiche, car la préversion destinée aux développeurs ne fournit ni comptes utilisateur ni authentification distante. Sur la boucle locale, ce comportement est cohérent : le contrôle d’accès est assuré par le système d’exploitation et seuls les processus locaux peuvent y accéder. 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 parcourent continuellement les ports peu courants. Considérez donc qu’un port 3080 publié sera découvert.

N’ouvrez pas le port 3080 dans votre pare-feu et ne définissez pas host du webserver sur 0.0.0.0 sur un VPS public. Cette combinaison permet à la première personne qui se connecte d’exécuter des commandes sur votre serveur.

Le même raisonnement s’applique à chaque 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 toutes laissent le harness lié à loopback.

  • Un tunnel SSH. Rien de nouveau 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 qui termine TLS (transport layer security) et exige un mot de passe avant de transmettre quoi que ce soit.

La différence entre ces méthodes tient au mécanisme qui achemine votre navigateur vers loopback. Aucune ne doit consister à déplacer le harness hors de 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 s’affiche.

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 champs 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 du VPS, après l’arrivée de votre trafic sur celui-ci. Il désigne la loopback du VPS, pas celle de votre ordinateur. C’est précisément l’adresse affichée par dsh. C’est 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 ainsi un redirecteur, sans shell. Pour créer un tunnel en arrière-plan qui signale 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 délais d’expiration du NAT (network address translation) sur les routeurs des cafés et des 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 d’adresse locale contient 0.0.0.0:3080 à la place, l’interface Web est disponible 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. Sinon, le nom du processus associé à un socket appartenant à un autre utilisateur est masqué.

Lorsque le tunnel refuse de démarrer

SSH affiche ce message, puis se ferme :

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 correspondre.

Si le tunnel démarre, mais que le navigateur signale un refus de connexion ou une réponse vide, le trafic est bien arrivé sur le VPS, mais aucun service ne répond à l’autre extrémité. Soit dsh s’est fermé, soit il a utilisé 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 s’arrête lorsque son shell se ferme. Le harness s’arrête donc dès que vous vous déconnectez. Lancez-le dans tmux ou avec un service systemd utilisateur. C’est le même problème que celui résolu dans maintenir un agent de codage actif sur un VPS. Pendant que vous configurez la partie SSH, renforcer la sécurité de SSH sur votre VPS est une bonne première étape, 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 à localhost:3080 lui-même. Le harness reste ainsi lié à loopback, sans modifier 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 ouvrir de port sur l’interface publique. Les certificats HTTPS doivent être activés pour votre tailnet. Sinon, serve ne dispose d’aucun certificat à présenter. Pour arrêter le service, 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 runtime d’agent non authentifié sur un port ouvert. Les deux commandes se ressemblent presque, mais produisent des résultats opposés. Lisez donc la différence entre Tailscale Serve et Funnel avant d’exécuter l’une ou l’autre. Tailscale comme réseau privé explique la configuration elle-même.

Accéder au service 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 barrière entre un inconnu et l’exécution de commandes sur votre serveur. Choisissez cette méthode si 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. Il 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. Une reconfiguration échoue si le fichier est incorrect et conserve la configuration active. Lisez donc l’erreur au lieu de redémarrer le service à l’aveugle.

Trois de ces lignes du proxy sont nécessaires. Les en-têtes Upgrade et Connection autorisent le handshake 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. Sinon, une longue exécution de l’agent est interrompue au milieu de la réponse et l’interface semble figé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. Choisir entre nginx, Caddy et Traefik décrit la même configuration avec des certificats automatiques.

Fermez le port 3080 dans le firewall, quel que soit le proxy choisi. Le seul accès doit passer par le proxy authentifié. Notions de base sur le firewall ufw présente les règles à utiliser. L’authentification basique sur TLS constitue un niveau minimal, pas un modèle de sécurité complet : quiconque possède ce mot de passe dispose d’un shell sur votre serveur. Privilégiez le tunnel lorsque c’est possible.

Comment modifier le port sur lequel le serveur web de dsh écoute ?

--port appartient à l’application web, pas au launcher. La documentation de la CLI fournit 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 flags et transmet tout ce qui les suit au profil démarré. Les flags du launcher doivent donc être placés en premier. Le premier token que le launcher ne reconnaît pas commence les arguments de l’application. Placez --port après le profil, jamais avant.

Lisez l’URL affichée par la commande au lieu de la déduire, car cette ligne indique l’adresse sur laquelle le serveur s’est effectivement lié. Mettez ensuite à jour le dernier champ de votre tunnel :

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

Pour modifier le port de façon permanente, définissez-le 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 templates fournis, dans ~/.dsh. Pour voir la configuration réellement appliquée après la composition 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 évite tout 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 » ?

Parce qu’un autre processus utilise déjà cette adresse et ce port. Le noyau refuse donc le second bind. Node affiche généralement l’erreur ainsi :

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, mais qui s’exécute encore 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à l’interface loopback.

Figez la version, car il s’agit d’un aperçu destiné aux développeurs

Le README est explicite : DeepSeek Harness est en aperçu destiné aux développeurs et évolue rapidement. Des changements incompatibles sont donc à prévoir.

npx @deepseek-ai/dsh web utilise systématiquement la version publiée la plus récente à chaque exécution. Un serveur auquel vous n’avez pas touché depuis une semaine peut donc lancer un autre CLI au démarrage suivant, avec des options différentes. 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 paquet publié est la version 0.1.0-rc.7. Vérifiez ce qu’un simple npx installerait avant de l’accepter :

npm view @deepseek-ai/dsh version

Lors des versions d’aperçu, les options peuvent passer du launcher à l’application web. Si --port ne se comporte plus comme décrit dans ce guide, demandez à l’application sa propre liste d’options au lieu de les 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 une procédure plus courte consacrée uniquement à l’étape d’accès, accéder à l’interface web 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 la commande. L’interface Web DeepSeek Harness est liée à l’adresse loopback du VPS. Seuls les processus exécutés sur le VPS peuvent donc s’y connecter. Votre ordinateur portable possède sa propre adresse loopback, et aucun processus n’y écoute sur le port 3080. Transférez le port avec SSH à l’aide de 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 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 preview développeur ne présente aucun écran de connexion. Une liaison sur toutes les interfaces d’une adresse IP publique permet à toute personne qui atteint le port 3080 d’exécuter des commandes sur votre serveur. Conservez la liaison sur 127.0.0.1, laissez le port 3080 fermé au niveau du 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 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. Démarrez-le dans une session tmux, puis détachez-la avec Ctrl-b d, ou exécutez-le comme service utilisateur systemd 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 celui-ci ait un processus parent qui survive à votre session de connexion.

Pourquoi l’interface Web dsh se fige-t-elle au milieu d’une longue exécution d’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 lors d’une longue étape de l’agent. Définissez proxy_read_timeout 3600s; dans le bloc location. Ajoutez proxy_buffering off; afin que la sortie soit transmise au navigateur au fur et à mesure. Transmettez également 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 jamais de mise à jour.