Deploy DeepSeek Harness on a remote server over SSH

Install & Get StartedPublished 2026-09-10Author: DeepSeek Plugin Market
DeepSeek HarnessDSH pluginremote deploySSH tunnelserver
Deploy DeepSeek Harness on a server with npx or a source build, then note it binds only to 127.0.0.1:3080 and reach it safely through an SSH local port forward.

The hard part of deploying DeepSeek Harness to a remote server is not installing it, but using it safely afterwards. By design, dsh web binds only to 127.0.0.1 and rejects --host 0.0.0.0, and the CLI offers no network deployment mode, so the correct move is not to open a port but to bring the remote loopback address to your local browser with an SSH local port forward.

Get DeepSeek Harness running on the server: Node.js and two paths

On the server side there is only one job: make dsh run there, still on the server's own 127.0.0.1:3080 (source).

  1. Prepare the runtime. Install Node.js on the server, plus pnpm if you plan to build from source. Expected: node -v prints a version.
  2. Pick a start path. For the no-install path run npx @deepseek-ai/dsh web; for the source path git clone, then pnpm install, pnpm run build, and finally pnpm dsh web. Expected: the service listens on 3080 and the terminal prints an access address.
  3. Force server-only mode. Add --no-open so it never tries to find a browser on a headless machine. Expected: it only starts the server and prints the address.
  4. Change the port as an app argument. The port belongs to the web app, so write dsh --profile web --port 8080. Expected: the launcher parses only its own flags and hands the first unrecognized argument to the app.

A headless server is not a blocker, since DeepSeek Harness already separates the server from the browser: in a server environment it prints the address instead of opening a page.

Why you cannot expose the DeepSeek Harness DSH web publicly: 127.0.0.1 and 0.0.0.0

This is a deliberate official trade-off rather than a missing setting: the web app can run commands with the Host user's authority, so offering an all-interfaces mode would imply support for network deployment without TLS or a proxy convention (source).

  1. The bind address is loopback. dsh web binds 127.0.0.1 and rejects --host 0.0.0.0. Expected: other machines on the LAN cannot connect, which is exactly the intent.
  2. The CLI has no network mode. Custom-interface, all-interfaces, and IPv6 modes are not offered. Expected: do not count on a command-line flag to publish the service.
  3. Authentication does not authorize remote deployment. Process token and browser cookie authentication do not widen that deployment contract. Expected: even with authentication, the official docs provide no TLS, forwarded-header interpretation, or proxy support for remote deployments.
  4. How it behaves over SSH. Starting over SSH prints only the host URL. Expected: the local forwarding address is held by the SSH client or editor, so the server reports only its own side.

Port and authentication troubleshooting is covered in web access and port and configuring the Web UI.

Three safe ways to reach DeepSeek Harness: SSH tunnel, server-local, headless

There are three ways to use DeepSeek Harness remotely, and you pick by whether you need an interface (source).

  1. SSH local port forward (recommended). On your own machine run ssh -L 3080:127.0.0.1:3080 <user>@<server> and keep the session open. Expected: local 3080 maps to the server's 127.0.0.1:3080, traffic rides an encrypted tunnel, and the server exposes no port.
  2. Fetch the token URL and open it. Copy the printed root URL carrying ?token= from the server console and paste it into your local browser. Expected: the token is exchanged for a session cookie and redirects to the clean root path; the token changes after a restart, so fetch it again.
  3. Use it on the server only. Skip forwarding entirely and work in command-line modes. Expected: ideal when you only want to run jobs and no interface.
  4. Headless batch work. Run dsh --profile headless "job" for a fresh session that prints the final answer, or dsh --profile sdk to serve clients over JSON-RPC. Expected: no web entry point at all, which suits scheduled and automated tasks.
  5. Do not substitute public exposure for forwarding. For example, putting a reverse proxy in front of 3080. Expected: that crosses a boundary the official docs explicitly do not support, and the authentication mechanism was not designed for it.

How the run modes differ is covered in choosing a dsh run mode.

Remote DeepSeek Harness troubleshooting and long-running use on a server

On a server the first-hand evidence is the logs, not the interface, because the interface may not open at all (source).

  1. Confirm the process and port. Check on the server whether the process is alive and 3080 is listening. Expected: a missing process means the service exited, so read the terminal output first.
  2. Read the logs by category and level. Filter the system log by categories such as install, uninstall, update, and diagnostics, and by level. Expected: the failure points at a specific stage instead of a vague "it will not start".
  3. Dry-run configuration changes. Use --dump-default-config or --dump-config to inspect the composed configuration without starting. Expected: misconfiguration surfaces immediately rather than after repeated restarts.
  4. Host it yourself for long-running use. The official docs describe no service or daemon mode. Expected: to keep it running on a server, use a terminal multiplexer such as tmux or screen, or your own system service, and be clear about which user owns $DSH_HOME.
  5. Read the notes before upgrading. Harness upgrades follow the install path. Expected: the command table is in the update commands cheat sheet.
System Logs

Caveats and limits of deploying DeepSeek Harness remotely

  1. The bind address is not configurable. 127.0.0.1 and the rejection of --host 0.0.0.0 are official decisions, and any workaround falls outside supported use.
  2. Authentication is not a deployment plan. Tokens and cookies solve credential handling for same-machine access, not TLS, reverse proxies, or remote deployment conventions.
  3. The token changes every start. Remote access means fetching the token URL from the server console again; you cannot bookmark it in advance.
  4. A dropped tunnel is not a crashed server. Closing the SSH session breaks the forward and the interface stops loading, while the service keeps running.
  5. Own the data directory clearly. Whichever user runs dsh gets that user's $DSH_HOME, so switching users effectively switches configuration and DSH plugins.

To install DSH plugins on the server, start it with the no-install path and browse DSH Plugin Hub's market by category; no manual dependency edits are needed.

Sources: DeepSeek Harness README (official repository), dsh CLI README (official repository), Agent Note: explicit web bind address, Agent Note: browser token authentication

FAQ

Can I deploy DeepSeek Harness on a public server and open it to the internet?

No. DeepSeek Harness binds dsh web to 127.0.0.1 and rejects --host 0.0.0.0, the CLI offers no network deployment mode, and the official docs state that browser authentication does not imply support for network deployment, TLS, or proxy configuration. The correct approach is an SSH local port forward, not an exposed port.

How do I start DeepSeek Harness on a server with no graphical interface?

A headless server is not a problem, because DeepSeek Harness separates the server from the browser: run npx @deepseek-ai/dsh web on the server and it only tries to open a browser on local starts, printing the address in server environments instead. Add --no-open to guarantee the server runs without a browser.

Why does DeepSeek Harness print only the host URL when started over SSH?

Because the local forwarding address is held by the SSH client or editor, DeepSeek Harness cannot know which local port you mapped, so it prints only the server-side address. Pair it with an ssh -L local port forward, then open that same address in your local browser.

How does the startup token work when I reach DeepSeek Harness through an SSH tunnel?

DeepSeek Harness generates a random startup token on every launch and prints one root URL carrying it. After setting up the SSH tunnel, open that token URL from the server console in your local browser; it exchanges the token for a cookie and redirects to the clean root path, after which you use it normally.

What if I want to run DeepSeek Harness batch jobs on the server without exposing any interface?

You do not need an interface, because DeepSeek Harness ships headless and sdk profiles: dsh --profile headless "job" runs a fresh session, prints the final answer, and exits, while dsh --profile sdk serves SDK clients over JSON-RPC. Neither mode needs a browser or exposes a web entry point.

Related Terms

127.0.0.1 binding
A 127.0.0.1 binding means the DeepSeek Harness web service listens only on the loopback address, reachable from a browser on the same machine but never from the LAN or the internet. It is a deliberate official choice that avoids implying support for network deployment without TLS and a proxy convention.Agent Note: explicit web bind address
SSH local port forward
An SSH local port forward is a way to map a local port onto a remote server's loopback address using `ssh -L`. For DeepSeek Harness it makes your local browser talk to local 3080 while the traffic travels through an encrypted tunnel to the server's 127.0.0.1:3080, so no port is exposed publicly.DeepSeek Harness README (official repository)
startup token
The startup token is a random credential DeepSeek Harness generates on every process start, printed once inside the root URL and never persisted. Visiting that URL exchanges it for a host-only, HttpOnly session cookie; the token changes on each restart, so remote access requires fetching it again.Agent Note: browser token authentication
headless profile
The headless profile is a built-in DeepSeek Harness mode with no interface: `dsh --profile headless "job"` starts a fresh persistent session and prints the final answer before exiting. It suits batch jobs on a server because it needs no browser and exposes no web entry point.dsh CLI README

Sources