Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion .github/workflows/build-dsh.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ jobs:
steps:
- uses: actions/checkout@v4

- uses: docker/setup-qemu-action@v3

- uses: docker/setup-buildx-action@v3

- uses: docker/login-action@v3
Expand All @@ -32,22 +34,38 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# resolve the current "latest" dsh version once, up front, so the build
# is pinned to a concrete version and the image can be tagged with it
# (otherwise every rebuild silently floats to whatever npm has that day).
- id: dsh_version
run: |
set -euo pipefail
version=$(curl -fsSL https://registry.npmjs.org/@deepseek-ai/dsh | jq -r '."dist-tags".latest')
if [ -z "$version" ] || [ "$version" = "null" ]; then
echo "failed to resolve @deepseek-ai/dsh latest version" >&2
exit 1
fi
echo "version=$version" | tee -a "$GITHUB_OUTPUT"

- id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=sha,prefix=sha-
type=raw,value=${{ steps.dsh_version.outputs.version }}

- uses: docker/build-push-action@v6
with:
context: deepseek-harness
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
# npm mirror default; set NPM_REGISTRY var in repo settings to override
# DSH_VERSION pinned to the version resolved above for reproducibility
build-args: |
NPM_REGISTRY=${{ vars.NPM_REGISTRY || 'https://registry.npmmirror.com' }}
DSH_VERSION=${{ steps.dsh_version.outputs.version }}
cache-from: type=gha
cache-to: type=gha,mode=max
23 changes: 22 additions & 1 deletion deepseek-harness/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,32 @@ FROM node:22-bookworm-slim
ARG NPM_REGISTRY=https://registry.npmmirror.com
ENV NPM_REGISTRY=${NPM_REGISTRY}

# dev tools for plugin development: git (clone/pull plugin repos), vim (quick
# in-container edits), build-essential (native module compiles via pnpm).
# Small footprint, kept in the same image so one image serves both plain
# usage and plugin dev — no need to maintain a second image.
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends git vim build-essential ca-certificates; \
rm -rf /var/lib/apt/lists/*

# pnpm: dsh forwards `dsh plugin ...` to pnpm inside the profile dir
RUN --mount=type=cache,target=/root/.npm \
set -eux; \
printf 'registry=%s\n' "$NPM_REGISTRY" > /usr/local/etc/npmrc; \
npm config set registry "$NPM_REGISTRY"; \
npm install -g @deepseek-ai/dsh
corepack enable; \
corepack prepare pnpm@latest --activate; \
pnpm config set registry "$NPM_REGISTRY" --global

# dsh version to install: pin to a resolved version for reproducible builds;
# defaults to "latest" for ad-hoc local builds (CI resolves and pins this).
ARG DSH_VERSION=latest

RUN --mount=type=cache,target=/root/.npm \
npm install -g "@deepseek-ai/dsh@${DSH_VERSION}"

# dsh home: mount here to persist config/plugins/sessions
ENV DSH_HOME=/data/dsh
Expand Down
18 changes: 16 additions & 2 deletions deepseek-harness/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

| 文件 | 作用 |
|---|---|
| `Dockerfile` | 基于 `node:22-bookworm-slim`,全局安装 `@deepseek-ai/dsh` |
| `Dockerfile` | 基于 `node:22-bookworm-slim`,全局安装 `@deepseek-ai/dsh`;同时带 git/vim/build-essential/pnpm,一个镜像兼顾日常使用和插件开发 |
| `run.sh` | 构建/启动/停止/看日志/进容器的辅助脚本 |
| `data/dsh/` | 挂载的配置目录(自动创建),容器内路径 `/data/dsh` |

Expand Down Expand Up @@ -40,6 +40,20 @@ CONFIG_DIR=/srv/dsh ./run.sh run

删除容器后重建,数据仍在。

## 插件开发

镜像里已经装好 git / vim / build-essential / pnpm(`dsh plugin` 子命令会转发给 pnpm),不需要单独一个开发镜像。挂载本地插件源码目录:

```bash
PLUGIN_DIR=~/code/my-dsh-plugin ./run.sh run
```

容器内路径固定为 `/data/dsh/plugin-src`。进容器操作(装依赖、`pnpm link`、跑 `dsh plugin --profile <name> add ...` 等):

```bash
./run.sh shell
```

## 常用命令

```bash
Expand All @@ -50,7 +64,7 @@ CONFIG_DIR=/srv/dsh ./run.sh run
./run.sh shell # 进入容器 shell
```

可调环境变量:`IMAGE_NAME` `IMAGE_TAG` `CONTAINER_NAME` `HOST_PORT` `NPM_REGISTRY` `CONFIG_DIR`。
可调环境变量:`IMAGE_NAME` `IMAGE_TAG` `CONTAINER_NAME` `HOST_PORT` `NPM_REGISTRY` `CONFIG_DIR` `PLUGIN_DIR`

## 手动 docker 命令

Expand Down
15 changes: 14 additions & 1 deletion deepseek-harness/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,20 @@ CONTAINER_NAME="${CONTAINER_NAME:-dsh}"
NPM_REGISTRY="${NPM_REGISTRY:-https://registry.npmmirror.com}"
# config dir mounted into the container (persisted config/plugins/sessions)
CONFIG_DIR="${CONFIG_DIR:-$PWD/data/dsh}"
# optional: local plugin source dir for plugin development, mounted into the
# container so you can `dsh plugin --profile <name> add /data/dsh/plugin-src/<pkg>`
# or pnpm-link it from inside the container (see: run.sh shell). Unset by default.
PLUGIN_DIR="${PLUGIN_DIR:-}"

mkdir -p "$CONFIG_DIR"

# extra -v args, appended only when PLUGIN_DIR is set
MOUNT_ARGS=()
if [[ -n "$PLUGIN_DIR" ]]; then
mkdir -p "$PLUGIN_DIR"
MOUNT_ARGS+=(-v "$PLUGIN_DIR:/data/dsh/plugin-src")
fi

case "${1:-run}" in
build)
docker build --build-arg NPM_REGISTRY="$NPM_REGISTRY" -t "$IMAGE_NAME:$IMAGE_TAG" .
Expand All @@ -25,11 +36,13 @@ case "${1:-run}" in
docker run -d --name "$CONTAINER_NAME" \
--network host \
-v "$CONFIG_DIR":/data/dsh \
"${MOUNT_ARGS[@]}" \
-e NPM_REGISTRY="$NPM_REGISTRY" \
--restart unless-stopped \
"$IMAGE_NAME:$IMAGE_TAG"
echo "dsh web UI: http://127.0.0.1:3080 (host network mode)"
echo "config dir: $CONFIG_DIR"
[[ -n "$PLUGIN_DIR" ]] && echo "plugin source dir: $PLUGIN_DIR -> /data/dsh/plugin-src"
;;
stop)
docker rm -f "$CONTAINER_NAME"
Expand All @@ -42,7 +55,7 @@ case "${1:-run}" in
;;
*)
echo "Usage: $0 {build|run|stop|logs|shell}"
echo "Env: IMAGE_NAME IMAGE_TAG CONTAINER_NAME NPM_REGISTRY CONFIG_DIR"
echo "Env: IMAGE_NAME IMAGE_TAG CONTAINER_NAME NPM_REGISTRY CONFIG_DIR PLUGIN_DIR"
exit 1
;;
esac
Loading