moelin/deepseek-harness Docker Image
DeepSeek Harness的Docker镜像,提供轻量级运行时和带开发工具的工作站版本,支持网页用户名密码登录,多架构兼容,需持久化存储应用状态以确保数据不丢失。
DeepSeek Harness
DeepSeek Harness on Docker Hub publishes two image families:
- a lightweight runtime image for normal deployments
- a workstation image with development tools, a persistent HOME volume for user-installed toolchains, and the same
/dataapplication-state bind
Both variants are built from the same release pipeline and are published as multi-arch images for linux/amd64 and linux/arm64.
The browser authentication layer is provided by a custom https://github.com/caddyserver/caddy build with https://github.com/greenpau/caddy-security and https://github.com/mholt/caddy-ratelimit. Its entry point is a standard username/password web form, not WebAuthn or passkeys, so browser password managers can autofill it. Built-in, proxy-aware limits protect username and password submissions at the image boundary.
Current Release
These badges show the current non-floating release values automatically. Use the value shown in the badge when you want to pin a specific runtime or workstation release.
Tags
| Tag | Purpose |
|---|---|
latest | Runtime floating alias |
workstation | Workstation floating alias |
<DSH_VERSION> / <DSH_VERSION>-workstation | Versioned release tags generated by the release pipeline |
Persistence Requirement
Important for upgrades: the application-state persistence path has changed to /data. Both image variants require /data to be an exact bind mount or named-volume mount. Mounting only the legacy /home/node/.local/share/deepseek-harness path does not persist the current layout. To prevent silent state loss, the container prints a bilingual migration error and exits when /data is not mounted; recreate it with a persistent /data mount.
Both variants use /workspace as the image working directory and DSH_WORKSPACE default. The web Add workspace dialog opens at /workspace, and its Home shortcut also resolves there. In the workstation image, /home/node remains the user HOME and persistent tool volume; it is not the default project directory.
Quick Start
Runtime
bashdocker pull moelin/deepseek-harness:latest # Replace /opt/deepseek-harness with any persistent host directory you control. sudo install -d -m 0750 /opt/deepseek-harness/data /opt/deepseek-harness/workspace docker run -d \ --name deepseek-harness \ --restart unless-stopped \ -p 127.0.0.1:56789:8080 \ -e PUBLIC_URL=https://dsh.example.com \ -e AUTH_USERNAME=admin \ -e AUTH_PASSWORD=replace-with-a-unique-password-of-at-least-12-characters \ -v /opt/deepseek-harness/data:/data \ -v /opt/deepseek-harness/workspace:/workspace \ moelin/deepseek-harness:latest
The runtime requires a persistent mount at /data; the host bind shown above is the recommended layout for normal deployments. It stores:
/data/auth: authentication users and the persistent JWT signing key/data/caddy: Caddy configuration and certificates/state/data/dsh: DeepSeek Harness application state
The entrypoint normalizes the bind root and creates the required directories and files for the node user (UID/GID 1000:1000). Keep the bind source a regular directory and preserve its ownership and permissions when copying or restoring data.
Workstation
bashdocker pull moelin/deepseek-harness:workstation # Replace /opt/deepseek-harness with any persistent host directory you control. docker run -d \ --name deepseek-harness-workstation \ --restart unless-stopped \ -p 127.0.0.1:56789:8080 \ -e PUBLIC_URL=https://dsh.example.com \ -e AUTH_USERNAME=admin \ -e AUTH_PASSWORD=replace-with-a-unique-password-of-at-least-12-characters \ -v /opt/deepseek-harness/data:/data \ -v dsh-home:/home/node \ -v /opt/deepseek-harness/workspace:/workspace \ moelin/deepseek-harness:workstation
The workstation persists application state under /data, keeps user-installed pnpm, pipx, Cargo, and Go tools in the named dsh-home volume, and stores projects through the direct /workspace bind.
To migrate an older workstation deployment, keep its existing /home/node volume or direct /home/node/.local/share/deepseek-harness mount attached for the first start and add the new /data mount. When /data/auth is empty, the entrypoint copies the legacy workstation application state into /data. Subsequent containers still require /data; the legacy mount cannot replace it. The old path is not deleted automatically, so remove it only after you confirm the migrated /data copy is working.
If you are moving from an older runtime named volume such as dsh-data, copy its contents into the new host data directory before switching tags so the same authentication and JWT state is reused.
If you run the repository Compose files locally, they already use the package-local ./data/data, ./data/workspace, and dsh-home layout with the same split between application state, workspace files, and user-installed tools.
Configuration
Core settings
| Variable | Meaning |
|---|---|
PUBLIC_URL | Required browser origin, for example https://dsh.example.com. Use the exact public origin, not a subpath. |
AUTH_MODE | Login mode. Default caddy-security; none is only for deployments with another auth layer; dsh is reserved and fails closed. |
AUTH_USERNAME | Single login username. Default admin. |
AUTH_PASSWORD | Plaintext password, at least 12 characters. Set exactly one credential source. |
AUTH_PASSWORD_FILE | Readable secret file path for the password source. |
AUTH_PASSWORD_HASH | bcrypt:<cost>:<hash> form generated by Caddy. |
AUTH_TOKEN_LIFETIME | Token and cookie lifetime in seconds. Valid range: 300 to 2592000. |
CADDY_TRUSTED_PROXIES | Space-separated trusted proxy CIDRs, private_ranges (default), or none for direct client connections. |
AUTH_COOKIE_INSECURE | false for normal HTTPS deployments. true only for isolated HTTP tests, where cookies lose Secure and HttpOnly. |
DSH_TRUSTED_HOSTS | Optional comma-separated extra Host authorities when the app is reached through additional trusted origins. |
Recommended defaults:
| Variable | Default | Meaning |
|---|---|---|
PORT | 8080 | Container port where Caddy listens. Publish it through a loopback host port or private network. |
DSH_INTERNAL_PORT | 3080 | Internal DeepSeek Harness loopback port inside the container. Do not publish it directly. |
GOMEMLIMIT | 128MiB | Soft memory limit for Caddy's Go runtime only. It does not cap DSH workloads. |
GOMAXPROCS | 2 | Caddy Go runtime CPU scheduling limit. |
DSH_TELEMETRY_DISABLED | 1 | Disables DSH telemetry. |
The default login username is admin. There is no built-in default password; set exactly one credential source with AUTH_PASSWORD, AUTH_PASSWORD_FILE, or AUTH_PASSWORD_HASH.
Authentication rate limiting
The image limits username-stage POSTs to 10 per minute and password-stage POSTs to 10 per 10 minutes for each resolved client IP. Rejected requests return HTTP 429 with Retry-After. These budgets are fixed image defaults rather than runtime settings; changing them requires a custom rebuild and smoke test.
CADDY_TRUSTED_PROXIES controls which proxy hops Caddy trusts while resolving X-Forwarded-For from right to left. The default private_ranges matches the documented loopback/private reverse-proxy deployment. Set it to none when clients connect directly to Caddy. When a CDN or another proxy sits in front of 1Panel/OpenResty, normalize the real client IP in that outer proxy or list every trusted proxy range. Unrestricted /0 ranges are rejected. Keep a matching limit in the outer WAF or reverse proxy as defense in depth.
Backup and lifecycle
Stop the container before backing up /opt/deepseek-harness/data to obtain a consistent archive:
bashdocker stop deepseek-harness sudo tar -C /opt/deepseek-harness/data \ -czf /opt/deepseek-harness/dsh-data.tar.gz . docker start deepseek-harness
Restore only while the container is stopped, preferably into an empty data directory. A bind-mounted /data directory is not a Docker volume, so docker compose down --volumes, docker volume rm, and docker volume prune do not delete it. Remove the host directory separately only when its data is no longer needed.
The workstation dsh-home named volume must be backed up separately. Ordinary container removal and docker compose down preserve named volumes; docker compose down --volumes can remove them.
Notes
- Keep the container port loopback-bound and place it behind 1Panel/OpenResty or another reverse proxy that forwards
Host,X-Forwarded-Proto, a trustworthyX-Forwarded-Forchain, and WebSocket upgrade headers. PUBLIC_URLmust match the browser-visible origin exactly. If you use an IP address or a private certificate, the browser must trust that certificate chain first.- Plain HTTP is only for isolated test networks, and it requires
AUTH_COOKIE_INSECURE=true. - The workstation image includes Python, Go, Rust, Docker CLI client tools, and common build utilities, but no Docker daemon.
- Mount
/var/run/docker.sockonly when host Docker control is intentionally required.
Source
- GitHub source: https://github.com/okxlin/release-factory
- DeepSeek Harness builder docs: https://github.com/okxlin/release-factory/tree/main/deepseek-harness-builder
moelin/deepseek-harness Related Documentation
镜像拉取方式
您可以使用以下命令拉取该镜像。请将 <标签> 替换为具体的标签版本。如需查看所有可用标签版本,请访问 标签列表页面。
轩辕镜像加速拉取命令点我查看更多 deepseek-harness 镜像标签
DockerHub 原生拉取命令
用户好评
来自真实用户的反馈,见证轩辕镜像的优质服务
