Featured image of post DeepSeek Harness Docker 部署:带登录的 Web UI,手机也能开

DeepSeek Harness Docker 部署:带登录的 Web UI,手机也能开

不用装客户端:一条 Compose 把 DeepSeek Harness 跑在自己机器上,入口加用户名密码,手机浏览器也能开。Ubuntu 24.04 实测 0.2.1-rc.3,9 张截图 + 报错表。

先说结论

搜 deepseek harness,出来的词多半是「下载」「安装包」「桌面端」「手机版」。真去装会发现没有 exe 可双击——它本身就是一个跑起来的网页,装的是运行时,用的时候开浏览器。

这篇给最短的一条路:Docker 加一条 Compose,把 DeepSeek Harness 跑在你自己的机器上,入口挡一层用户名密码,手机浏览器也能打开。

三条命令先摆在这里,后面逐条解释:

docker pull docker.xuanyuan.run/moelin/deepseek-harness:0.2.1-rc.3
cd /www/wwwroot/deepseek-harness-moelin && docker compose up -d
# 浏览器打开 http://服务器IP:56789/

本文用 moelin/deepseek-harness:0.2.1-rc.3,Ubuntu 24.04 实测,下面的截图都是这次跑出来的。

DeepSeek Harness 是什么

DeepSeek 开源的 AI Agent 运行时。它管会话、工具、权限和网页界面,模型调用走你自己的 API Key。它本身不带模型权重,也不是推理服务器——你把 OpenAI 兼容的地址和 Key 填进去,它才有力气干活。

所以「安装」这个词不太适用。真正要装的是承载它的那一层:容器、端口、持久化目录、登录。这一层装好之后,换电脑、换手机、给同事用,都只是打开浏览器。

三种用法,先选一条

同一个运行时,常见的三种用法,差别不在功能,在数据和文件落在谁那里:

用法入口状态在哪适合谁
官方网页版浏览器打开官方站点平台侧先看看它长什么样,偶尔用
本机 CLI / TUI终端,npm 包 @deepseek-ai/dsh本机用户目录一个人用,习惯终端
自托管 Web UI(本篇)你自己机器的 IP:56789你的 /data 和 /workspace有常开主机、代码在内网、要给手机或同事用

选第三条的理由通常不是「更快」,而是「东西得留在自己手里」:仓库目录在内网,会话记录不该散落在别人服务器上,同事要试用又不能把能执行命令的服务裸挂出去。

环境要求

项目要求
系统Linux(命令按 bash 写)。macOS 把 /www/wwwroot/deepseek-harness-moelin 换成 ~/docker/deepseek-harness-moelin
DockerEngine + Compose V2(docker compose,不是老的 docker-compose)
架构amd64、arm64 都支持
磁盘压缩体积约 369 MB(amd64)/ 364 MB(arm64),解压后更大,/workspace 还要留空
端口宿主机 56789 → 容器 8080。别占宿主机 3000,那是前端开发的地盘
账号默认用户名 admin,密码自己设,至少 12 位,没有预置密码
docker --version
docker compose version

没装 Docker 的 Linux:

bash <(wget -qO- https://get.xuanyuan.cloud/docker.sh)

脚本跑不通就换备用地址 https://get.xuanyuan.me/docker.sh。更多见使用手册。

拉镜像:国内怎么拉得动

moelin/deepseek-harness 在 Docker Hub 上,直连经常卡在 Waiting。走轩辕镜像加速:

docker pull docker.xuanyuan.run/moelin/deepseek-harness:0.2.1-rc.3

一直卡在 Waiting 或者报 i/o timeout,说明本机还没配加速,先按国内镜像源配置把 daemon.json 改掉,再回来拉这个镜像。

这次 Ubuntu 24.04 上的输出:

0.2.1-rc.3: Pulling from moelin/deepseek-harness
124076035e7e: Pull complete
df311c1538a9: Pull complete
...
Status: Downloaded newer image for docker.xuanyuan.run/moelin/deepseek-harness:0.2.1-rc.3

拉取报 401、402,或者提示额度用完,原因都在订阅与配额上,见常见问题。

Docker Compose 部署

工作目录 Linux 用 /www/wwwroot/deepseek-harness-moelin,macOS 用 ~/docker/deepseek-harness-moelin。

1. 建目录

sudo mkdir -p /www/wwwroot/deepseek-harness-moelin/data \
  /www/wwwroot/deepseek-harness-moelin/workspace
sudo chmod 0750 /www/wwwroot/deepseek-harness-moelin/data \
  /www/wwwroot/deepseek-harness-moelin/workspace
sudo chown -R "$USER":"$USER" /www/wwwroot/deepseek-harness-moelin
cd /www/wwwroot/deepseek-harness-moelin

入口脚本会按容器用户 node(1000:1000)整理 /data,权限先给 0750 就够。

2. 写 compose.yaml

PUBLIC_URL 里的 IP 换成你的局域网地址,密码换成你自己的:

cat > compose.yaml <<'EOF'
services:
  deepseek-harness:
    image: docker.xuanyuan.run/moelin/deepseek-harness:0.2.1-rc.3
    container_name: deepseek-harness
    restart: unless-stopped
    ports:
      - "56789:8080"
    environment:
      PUBLIC_URL: http://192.168.1.35:56789
      AUTH_MODE: caddy-security
      AUTH_USERNAME: admin
      AUTH_PASSWORD: ChangeMe-DSH-2026!
      AUTH_COOKIE_INSECURE: "true"
      CADDY_TRUSTED_PROXIES: none
      DSH_TELEMETRY_DISABLED: "1"
      TZ: Asia/Shanghai
    volumes:
      - ./data:/data
      - ./workspace:/workspace
    healthcheck:
      test: ["CMD", "/usr/local/bin/healthcheck.sh"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 15s
EOF
配置说明
56789:8080宿主机 56789 → 容器里 Caddy 的 8080
PUBLIC_URL浏览器地址栏里那个地址,协议、IP、端口都要对,不能带路径
AUTH_PASSWORD至少 12 位。不要提交到公开仓库
AUTH_COOKIE_INSECUREHTTP 试用写 true;上了 HTTPS 必须改回 false
CADDY_TRUSTED_PROXIES浏览器直连写 none;前面还有反代写 private_ranges
./data:/data必挂。认证、签名密钥、Caddy 状态、会话都在这
./workspace:/workspace项目目录,界面里「主目录」就是它

3. 启动

docker compose up -d
docker compose ps

刚起来健康检查是 starting,十几秒后转 healthy:

NAME               STATUS                            PORTS
deepseek-harness   Up 6 seconds (health: starting)   0.0.0.0:56789->8080/tcp

启动后先看这三行日志

docker compose logs --no-color --tail=80 deepseek-harness
[entrypoint] trusted proxy parsing disabled; authentication limits use the direct peer address
[entrypoint] generated a persistent authentication signing key
[entrypoint] starting DeepSeek Harness 0.2.1-rc.3 on 127.0.0.1:3080

三行分别对应三件事:反代信任被关掉了(直连场景正常)、签名密钥已生成并写进 /data、应用在容器内 3080 上听,没有往外暴露。健康检查打的是 /healthz,未登录也会返回 ok,所以 healthy 只代表进程活着,不代表你能登录进去。

浏览器登录:默认账号 admin

打开 http://192.168.1.35:56789/,换成你的 IP:

  1. Sign In 页填用户名(本文是 admin),点 Proceed。
  2. Authentication 页填密码,点 Authenticate。

DeepSeek Harness 登录第一步:填用户名 admin,按钮是 Proceed

DeepSeek Harness 登录第二步:填密码,按钮是 Authenticate

登录提交是限速的。连着输错几次会返回 429,等提示的时间再试,猛点只会把等待时间拉长。

第一次进来要做三件事

1. 关掉预览说明

DeepSeek Harness 首次进入:预览版说明弹窗,顶部提示无法创建默认工作区

顶部那行「无法创建默认工作区,请通过 ‘选择工作区’ 选择文件夹」不是报错,是还没选目录。往下走一步就好。

2. 填 API Key

DeepSeek Harness 开始使用:可添加 API Key,或登录 DeepSeek 账号

密钥只放在网页设置里,别写进镜像,也别提交到仓库。想稍后填就先关弹窗,发消息之前补上。

填完提示 Key 无效,先查三处:复制时有没有带上空格、账户余额、这个 Key 有没有对应模型的权限。这三条能盖掉大部分「api 密钥无效」。

3. 选工作区

DeepSeek Harness 选择工作区:在「主目录」下新建 demo 文件夹

「主目录」对应容器里的 /workspace,也就是你挂的 workspace/。宿主机上的仓库先放进这个目录,再在选择器里打开——放在别处,界面里是看不到的。

选好之后是主界面:

DeepSeek Harness 主界面:探索未至之境,工作区 demo,标准模式

右下角先选模型再发消息。输入框支持 / 调指令、@ 引文件或历史会话。

插件、技能、MCP 在哪装

左侧「插件」是唯一入口,分两块:

区块有什么怎么开
内置插件配置子智能体、网页搜索、Agent 循环、终端默认在,按需开关
实验性插件智能体团队、语音输入、自动授权审查、开发者工具打开开关,刷新页面才出现

DeepSeek Harness 插件页:内置插件配置与实验性插件开关

装第三方技能或 MCP 时,容器得能出外网,否则会卡在下载阶段,表现为「点了没反应」或者列表一直空着。装完刷新页面。

左侧「自动化任务」是另一套东西:把会话里跑的任务存成定时任务,没建过就是空列表。

DeepSeek Harness 自动化任务页:空列表,可新建

工作区里还带一个终端,实测提示符是 node@…:/workspace/demo$,说明选中的目录确实落在挂载点下:

DeepSeek Harness 内嵌终端:bash,路径 /workspace/demo

手机上能不能用

能,因为它本身就是网页,不需要另外装客户端。

同一个 Wi-Fi 下:手机浏览器直接开 http://服务器IP:56789/,用同一套用户名密码登录。有两个前提:

  1. PUBLIC_URL 必须写成手机上访问的那个地址。写 127.0.0.1 或 localhost,只有本机能开,手机打开是白屏或直接报错。
  2. 服务器防火墙放行 56789。

不在同一网络时(4G、公司外网),必须上 HTTPS 反代,见下一节。把网页「添加到主屏幕」就是个图标,用起来和 App 差不多;屏幕窄,选择器和键盘会挤,改代码还是电脑上顺手。

报错对照表

现象原因处理
容器起来立刻退出,日志有双语迁移提示没挂 /data补上 ./data:/data 再启动
登录成功,一刷新又回登录页HTTP 下没设 AUTH_COOKIE_INSECURE=true,或 PUBLIC_URL 和地址栏不一致改环境变量,docker compose up -d 重建
启动就报凭证错误AUTH_PASSWORD、AUTH_PASSWORD_FILE、AUTH_PASSWORD_HASH 同时设了多个,或都不设只留 AUTH_PASSWORD,12 位以上
反复登录返回 429登录提交有限速按 Retry-After 等,别连续点
页面能开,发消息转圈或报连不上PUBLIC_URL 不匹配;反代没转发 WebSocket 与 X-Forwarded-*见「HTTPS 反代」一节
image is unavailable、manifest unknown标签写错,或镜像已被删用 0.2.1-rc.3,别用浮动标签
插件装到一半失败,列表空着容器出不了外网检查网络与镜像源,装完刷新
拉镜像 401 / 402加速地址的订阅或配额问题见常见问题

正式环境:HTTPS 反代

把端口收到本机,前面挂 1Panel / OpenResty / Nginx:

    ports:
      - "127.0.0.1:56789:8080"
    environment:
      PUBLIC_URL: https://dsh.example.com
      AUTH_COOKIE_INSECURE: "false"
      CADDY_TRUSTED_PROXIES: private_ranges

反代要转发 Host、X-Forwarded-Proto、X-Forwarded-For,并允许 WebSocket 升级:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

location / {
    proxy_pass http://127.0.0.1:56789;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
}

不要把容器 8080 直接映射成公网 0.0.0.0。这玩意儿能执行命令、能改文件,等于一个带网页界面的 shell。

备份、升级与标签

cd /www/wwwroot/deepseek-harness-moelin
docker compose stop
tar -C data -czf deepseek-harness-data.tar.gz .
docker compose start

升级只改 compose.yaml 里的标签,data/ 和 workspace/ 留着。旧版本如果只挂了 /home/node/.local/share/deepseek-harness,不能直接替代 /data;先两个都挂上,确认数据进去了再拿掉旧的。

标签是什么用不用
0.2.1-rc.3轻量运行时:Harness、Caddy 登录层、git/curl/pnpm 等基础工具用这个
0.2.1-rc.3-workstation再带 Python、Go、编译器和开发工具,/home/node 用命名卷需要容器内装工具链时换
latest / workstation浮动别名,下次发版会改指向别写进 Compose

用 workstation 变体时多一个命名卷,要单独备份:docker compose down 不会删卷,加 --volumes 才会。

常见问题

有没有手机 App,能装 apk 吗

本文这套是网页,手机用浏览器打开同一个地址,「添加到主屏幕」就够用。官方其他入口发行什么形态,以官网为准。

和官方网页版什么关系

同一个运行时。官方网页版打开就能用,会话在平台侧;自托管这套的登录状态和会话在 /data,项目文件在 /workspace。数据在谁那里,是这两个选择最大的差别。

能多人用吗

入口只有一套用户名密码,多人共用同一个账号。要分人、分权限,得自己在反代层再做一层认证。

为什么不用宿主机 3000 端口

本机前端开发常占 3000。容器对外听 8080,本文映射 56789,避开就行,不用改容器内部端口。

和 smanx、runzhliu 的镜像有什么区别

三者都是社区打包的 DeepSeek Harness,不是官方推理镜像。moelin/deepseek-harness 用定制 Caddy 做用户名密码登录,状态固定到 /data;smanx/deepseek-harness 侧重局域网代理与可选 Basic Auth;runzhliu/deepseek-harness 常用日志里的 token 链接进入。按登录方式和运维习惯选,本文只写 moelin。

没有 Compose 能装吗

能,用 docker run 一条命令跑起来,参数和 Compose 一一对应:

docker run -d --name deepseek-harness --restart unless-stopped \
  -p 56789:8080 \
  -e PUBLIC_URL=http://192.168.1.35:56789 \
  -e AUTH_MODE=caddy-security -e AUTH_USERNAME=admin \
  -e AUTH_PASSWORD='ChangeMe-DSH-2026!' \
  -e AUTH_COOKIE_INSECURE=true -e CADDY_TRUSTED_PROXIES=none \
  -v /www/wwwroot/deepseek-harness-moelin/data:/data \
  -v /www/wwwroot/deepseek-harness-moelin/workspace:/workspace \
  docker.xuanyuan.run/moelin/deepseek-harness:0.2.1-rc.3

长期用还是建议 Compose,改版本、改环境变量只用改文件,不用背一长串参数。

命令速查

docker pull docker.xuanyuan.run/moelin/deepseek-harness:0.2.1-rc.3
cd /www/wwwroot/deepseek-harness-moelin
docker compose up -d
docker compose ps
docker compose logs --no-color --tail=80 deepseek-harness
docker compose down

延伸阅读

使用 Hugo 构建
主题 Stack,作者 Jimmy