---
title: "Deploy DeepSeek Harness on NixOS | (Just Updated) Agent With All of Nixpkgs"
description: "DeepSeek's coding agent on nix. Password-gated, any package it needs."
category: "AI/ML"
url: https://railway.com/deploy/deepseek-harness-on-nixos-or-just-update
---

# Deploy DeepSeek Harness on NixOS | (Just Updated) Agent With All of Nixpkgs

DeepSeek's coding agent on nix. Password-gated, any package it needs.

**[Deploy DeepSeek Harness on NixOS | (Just Updated) Agent With All of Nixpkgs on Railway](https://railway.com/template/deepseek-harness-on-nixos-or-just-update)**

- **Creator:** SuperSlowSloth
- **Category:** AI/ML
- **Total deploys:** 1

## Template content

### deepseek-harness-nixos

- **Image:** ghcr.io/bon5co/deepseek-harness-nixos-railway:0.1.0-rc.6
- **Health check:** /healthz
- **Public domain:** Yes

## Documentation

# Deploy and Host DeepSeek Harness on NixOS on Railway

DeepSeek Harness (`dsh`) is DeepSeek's own open-source agent harness — the layer that turns a model
into an agent that can read your files, run shell commands, search the web, and keep working across
a long task. Everything in it is a plugin: models, tools, skills, sessions, sandboxes, storage,
loops, scheduling, and the UI itself.

This is the **nix** flavor. Same harness, same password gate, same persistence as the Ubuntu
template — but the agent's toolbox is the nix package manager instead of apt, so it can pull any of
nixpkgs at an exact pinned version, mid-session, without root.

## About Hosting DeepSeek Harness on NixOS

The hard part of hosting this is not the app, it is the exposure.

DeepSeek Harness has no authentication. Upstream states this plainly — "No TLS, auth, or origin
policy" — and its CLI *refuses* to bind a public address, erroring with "it would expose remote
code execution to the network". That refusal is correct: an agent with a shell tool on an open URL
is a remote-code-execution box on your Railway account, and a persistent volume means anyone who
finds it keeps their foothold across your redeploys.

So this template does not bypass that refusal. `dsh` stays bound to loopback exactly as upstream
intends, and a Caddy reverse proxy owns the public port, enforces HTTP basic auth, and forwards to
loopback — rewriting `Host` and `Origin` so the harness's own anti-DNS-rebinding fence stays
satisfied through the proxy. Unauthenticated requests to the UI, the API and the WebSocket all
return `401`, including ones that forge a loopback `Host` header. The gate cannot be switched off:
leave the password blank and the container generates a strong one on first boot and prints it once
to your deploy log.

The base is the nix package manager on a minimal userland — not a full NixOS with systemd, which in
an unprivileged container buys nothing. What you actually want from nix here is available at
runtime: the agent runs `nix profile add nixpkgs#ripgrep` (or ffmpeg, or postgres, or a specific
Python) and gets a cache-copied, exactly-pinned build in seconds, unprivileged, with no rebuild and
no sandbox flags.

Measured at 135 MiB idle — lighter than the Ubuntu flavor. **Plan floor is 1 GB (Trial or Hobby),
not Free.** Idle fits Free's 0.5 GB easily, but installing packages at runtime spikes to roughly
590 MB during the nixpkgs channel unpack, and Free's cap kills that with exit 137 and no useful
error. Since runtime installs are the whole point of this flavor, 1 GB is the honest floor.

## Why Deploy DeepSeek Harness on NixOS on Railway

- **The agent picks its own tools, reproducibly.** Any of nixpkgs, pinned exactly, fetched from the
  binary cache without root — not "whatever version the distro repo has today".
- **Always on, and reachable from anything.** The upstream quick start dies when you close your
  laptop. Here the session, memory and workspace live on a volume and you resume from your phone.
- **Gated by default, provably.** Unauthenticated UI, API and WebSocket requests all return `401`.
  Verified against the running container, not asserted.
- **Nothing to fill in but your model key.** Every platform setting is baked into the image rather
  than dumped on the deploy form as blank required fields.
- **Pinned, not floating.** Both the harness version and the base image digest are pinned, so a
  deploy today behaves the same as a deploy next month.

## Common Use Cases

- **A polyglot agent workspace** — one box where the agent can reach for a Rust toolchain, ffmpeg,
  or an old Python without you rebuilding an image for each.
- **A coding agent that outlives your laptop** — hand it a long refactor, close the lid, check the
  trajectory view later.
- **Reproducible agent runs** — pinned packages mean a task that worked last week still works, so a
  failure is the agent's, not a silent dependency bump underneath it.
- **A scratch environment you do not mind breaking** — the agent gets a real shell in a container
  one redeploy away from clean.

## Dependencies for DeepSeek Harness on NixOS Hosting

- A **DeepSeek API key** from [platform.deepseek.com](https://platform.deepseek.com). Other
  providers work too — DSH resolves each provider's key from a variable that provider's own entry
  in `settings.yaml` names.
- A **volume mounted at `/home/dsh`**, for sessions, config, credentials and the workspace.

### Deployment Dependencies

- [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) — the upstream project (MIT)
- [Product page](https://deepseek.com/harness/en/) — modes, plugin model, trajectory view
- [`@deepseek-ai/dsh`](https://www.npmjs.com/package/@deepseek-ai/dsh) — the published CLI
- [nixos/nix](https://hub.docker.com/r/nixos/nix) — the digest-pinned base image
- [Caddy](https://caddyserver.com/) — the authenticating reverse proxy in front of it

### Implementation Details

| Variable | Default | Purpose |
| --- | --- | --- |
| `DEEPSEEK_API_KEY` | — | Model access. The UI loads without it; the agent cannot answer. |
| `DSH_USERNAME` | `admin` | Basic-auth user. |
| `DSH_PASSWORD` | generated | Basic-auth password. Blank means *generated*, never *disabled*. |
| `DEEPSEEK_BASE_URL` | DeepSeek API | Point at a gateway or proxy instead. |

The request path:

```
browser ──TLS──> Railway edge ──> Caddy on $PORT   (basic auth; 401 without credentials)
                                       │
                                       └──> dsh web on 127.0.0.1:3080  (never reachable outside)
```

**What the volume does and does not keep.** A volume at `/home/dsh` persists your sessions, config,
credentials and the agent's files. It does **not** fully persist packages the agent installs, and
the reason is worth knowing because it looks like it should: `nix profile add` writes a manifest
under `/home/dsh/.nix-profile` (on the volume, survives) and the package itself into `/nix/store`
(in the image layer, does not). After a redeploy the manifest points at store paths that are gone;
re-running `nix profile add` repairs it as a binary-cache copy in seconds. If you want installs to
survive redeploys, mount a second volume at `/nix` as well.

**One caveat, stated plainly.** The gate is a single shared password over Railway's TLS. That is
the right gate for one operator running their own agent box. It is not multi-user access control,
and it does not protect you from someone who already has the password. If the workspace will hold
anything sensitive, put Cloudflare Access or a VPN in front as well.


## Similar templates

- [Chat Chat](https://railway.com/deploy/-WWW5r) — Chat Chat, your own unified chat and search to AI platform.
- [stella](https://railway.com/deploy/stella) — Self-host stella with web, API, Postgres, Redis, and object storage.
- [Hermes Agent | OpenClaw Alternative with Dashboard](https://railway.com/deploy/hermes-agent-or-openclaw-alternative-wit) — Self-Hosted Hermes AI Agent for Telegram, Discord & Slack

Open this page in a browser: https://railway.com/deploy/deepseek-harness-on-nixos-or-just-update
