Deploy DSH Coding Agent
Self-host DeepSeek Harness, DeepSeek's coding agent, behind a password
Just deployed
/data
Deploy and Host DSH (DeepSeek Harness) on Railway
DSH is the agent harness DeepSeek publishes as deepseek-ai/deepseek-harness: a full coding agent with file editing, a shell, file and web search, skills, planning, goals, subagents and workflows, driven from a browser instead of a terminal. This template runs it as a persistent web app on Railway, behind a password you set, with your DeepSeek API key already wired in.
About Hosting DSH
Upstream ships DSH as an npm package you run on your own laptop, and it deliberately refuses to serve itself to a network. Ask it to bind a public address and it stops with --host 0.0.0.0 is intentionally not supported yet for safety: it would expose remote code execution to the network. That refusal is correct: the harness drives an agent that runs shell commands, and the product has no login of its own.
Hosting it therefore means adding the missing layer rather than removing the guard. In this template the harness still binds loopback exactly as upstream intends, and a Caddy reverse proxy holds the public port with HTTP basic auth in front of it. Everything that reaches the agent has already passed a password. The proxy also rewrites the forwarded Host to the loopback authority, which is what keeps the Settings, Models and credential pages working: upstream pins that privileged plane to a loopback caller, so a naive proxy serves a UI that loads and then refuses to configure anything.
The result is a single container with a volume, an agent that keeps its sessions and your files across redeploys, and a login you control.
Common Use Cases
- A coding agent you can reach from any browser, including a phone or a tablet, without leaving a laptop running.
- A long-lived scratch environment where an agent clones a repository, works on it over days, and keeps its session history.
- Trying DSH and its plugin ecosystem without installing Node or a toolchain locally.
Dependencies for DSH Hosting
- A DeepSeek API key from platform.deepseek.com. The agent cannot answer without one, but you can add it after deploying rather than before.
Deployment Dependencies
- DeepSeek Harness
0.1.0-rc.7, MIT licensed, from deepseek-ai/deepseek-harness. - Caddy 2, serving the public port with basic auth.
- One Railway volume, mounted at
/data.
Implementation Details
What you set at deploy time
| Variable | Required | What it does |
|---|---|---|
DEEPSEEK_API_KEY | no | Your DeepSeek key. Paste it to have the agent ready on first load, or leave it blank and add it in the app's first-run dialog. |
DSH_UI_USERNAME | yes | The username you want to log in with. The deploy form asks for it. |
DSH_UI_USERPASS | yes | The password you want to log in with, minimum 12 characters. The deploy form asks for it, and the container refuses to start below 12. |
DSH_WORKSPACE | no | Where the agent works, defaults to /data/workspace. |
DSH_HOME | no | Harness home, defaults to /data/.dsh. |
First run
- Open the deployment URL. The browser asks for the username and password you chose at deploy time.
- Dismiss DeepSeek's testing notice.
- If you left
DEEPSEEK_API_KEYblank, paste your key into the "Add an API key to get started" dialog and click Save and continue. - Click Choose workspace, select
workspace, click Open. - Type a task and send it.
Step 4 uses an in-app directory browser rather than an operating system file dialog. DSH picks that automatically on a headless host, so it works here and would not have on a desktop.
The password is the entire security boundary
You choose it on the deploy form. Anyone who has it can run arbitrary commands in this container and read your DeepSeek API key, so make it unguessable and do not reuse one you use elsewhere. The container refuses to boot on anything under 12 characters and says why in the deploy logs, rather than quietly serving a weak one.
What persists
The volume mounts at /data. /data/.dsh holds sessions, settings and the credential store; /data/workspace holds what the agent edits. Both survive redeploys. Anything written elsewhere in the container does not.
Getting your code in
No git remote is wired up for you. From a session, ask the agent to clone what you want into the workspace, or use the shell it already has. Credentials for private repositories are yours to add and land in the volume.
Using another provider
The Models page under Settings accepts keys for other providers and custom OpenAI compatible endpoints. A key stored there wins over .env layers but not over DEEPSEEK_API_KEY in the environment, which is deliberate upstream behaviour. To make the UI the source of truth for DeepSeek specifically, clear the DEEPSEEK_API_KEY service variable.
Version pinning
The image pins 0.1.0-rc.7. DSH is in developer preview and its own README warns of compatibility breaking changes, which is why this does not track latest. To move, change the service image tag to a newer build and redeploy.
A patched client
The harness decides whether to offer its settings UI by reading the page's own hostname, with no setting to override it. On any real domain it refuses, and Settings shows "settings are unavailable in this browser". This image rewrites that single expression so the Settings, Models and credential pages work for the deployer who owns the box. Upstream gates it because those methods are loopback-only until authentication exists; here authentication exists, in front of the whole app. Nothing requiring a desktop is enabled by the change.
Known rough edges
- The browser logs a 401 for
/manifest.webmanifest. Browsers fetch a web app manifest without credentials, so the proxy declines it. Nothing in the app depends on it; it is left behind the password rather than exposed so an unauthenticated scanner cannot fingerprint what is running here. - DeepSeek shows an internal testing notice on first load. That is upstream's, not this template's.
Why Deploy DSH on Railway?
Railway supplies the two things this needs and a laptop does not: an address that stays up, and a disk that survives a restart. The volume keeps sessions and work in progress, so a session started on a desktop continues on a phone. A single container keeps the agent reachable only through the proxy that authenticates it, which is the property that makes hosting a shell-running agent defensible at all.
Deploys are one click, the password is generated for you, and the only thing you have to supply is your own DeepSeek key.
Template Content
DSH_UI_USERNAME
Username you will log in with.
DSH_UI_USERPASS
Password you will log in with, minimum 12 characters. This is the ONLY thing between the internet and an agent that can run shell commands on this container, so make it unguessable and do not reuse one. The container refuses to start if it is shorter than 12 characters.