1
0
mirror of https://github.com/sredevopsorg/deepseek-kubernetes-sandbox.git synced 2026-11-03 01:13:24 +00:00
Files
deepseek-kubernetes-sandbox/README.md
Nicolás Georger f3d4312089 Initial commit
Signed-off-by: Nicolás Georger <info@sredevops.org>
2026-10-21 00:39:54 -03:00

152 lines
6.5 KiB
Markdown

Here is the complete updated Dockerfile incorporating the hoisted deploy fix and the dependency patch. The key changes versus the last version are in the deploy block: `--legacy` is dropped, `node-linker=hoisted` and `inject-workspace-packages` are enabled, and the missing workspace peer is added via the `workspace:*` protocol.
```dockerfile
# syntax=docker/dockerfile:1.7
ARG NODE_BUILD_IMAGE=docker.io/node:24-trixie
ARG NODE_RUNTIME_IMAGE=docker.io/node:trixie-slim
# ---------------------------------------------------------------------------
# Build stage
# ---------------------------------------------------------------------------
FROM ${NODE_BUILD_IMAGE} AS build
ARG DSH_REPO=https://github.com/deepseek-ai/deepseek-harness.git
ARG DSH_VERSION=dsh-v0.2.1-rc.2
ARG PNPM_VERSION=11.28.5
# CI=true skips the repository's lefthook postinstall in the container.
ENV CI=true \
NODE_OPTIONS=--max-old-space-size=4096
RUN corepack enable \
&& corepack prepare "pnpm@${PNPM_VERSION}" --activate
WORKDIR /src
# Exact upstream tag, e.g. dsh-v0.2.1-rc.2.
RUN git clone --depth 1 --branch "${DSH_VERSION}" "${DSH_REPO}" .
RUN pnpm install --frozen-lockfile
# ── Workaround for upstream packaging defect ──────────────────────────────
# dsh-app-boot statically imports @deepseek-ai/cordis-plugin-group, which is
# only a peer/workspace dependency and is omitted by `pnpm deploy --prod`.
# Promote it to a real dependency of @deepseek-ai/dsh so it is always part of
# the deploy closure.
RUN pnpm --filter @deepseek-ai/dsh add @deepseek-ai/cordis-plugin-group@workspace:*
# ──────────────────────────────────────────────────────────────────────────
# Builds native addon, Host/Client bundles, and the Web frontend.
RUN pnpm run build
# ── Production deploy closure ────────────────────────────────────────────
# A hoisted (npm-style) node_modules is required: the default isolated pnpm
# layout drops peer dependencies such as @deepseek-ai/cosmokit from the
# deployed tree, causing ERR_MODULE_NOT_FOUND at runtime. `--legacy` is
# intentionally NOT used, so pnpm's modern deploy binds peers correctly.
RUN pnpm --config.node-linker=hoisted \
--config.inject-workspace-packages=true \
deploy --prod /opt/dsh \
&& test -f /opt/dsh/lib/bin.js \
&& test -d /opt/dsh/node_modules/@deepseek-ai/cosmokit \
&& test -d /opt/dsh/node_modules/@deepseek-ai/cordis-plugin-group \
&& node /opt/dsh/lib/bin.js web --help >/dev/null
# ──────────────────────────────────────────────────────────────────────────
# ---------------------------------------------------------------------------
# Runtime stage
# ---------------------------------------------------------------------------
FROM ${NODE_RUNTIME_IMAGE} AS runtime
ARG DSH_VERSION
LABEL org.opencontainers.image.title="DeepSeek Harness Web" \
org.opencontainers.image.version="${DSH_VERSION}" \
org.opencontainers.image.source="https://github.com/deepseek-ai/deepseek-harness"
ENV NODE_ENV=production \
HOME=/home/node \
DSH_HOME=/home/node/.dsh \
DSH_PORT=3080 \
PATH="/app/node_modules/.bin:${PATH}"
# git/ripgrep are useful for DSH agent tools; tini handles signals.
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
git \
ripgrep \
tini \
&& rm -rf /var/lib/apt/lists/* \
&& install -d -o node -g node -m 0755 /workspace "${DSH_HOME}"
COPY --from=build --chown=node:node /opt/dsh /app
COPY <<'EOF' /usr/local/bin/dsh-entrypoint
#!/bin/sh
set -eu
: "${DSH_PORT:=3080}"
: "${DSH_HOST:=}"
DSH_PUBLIC_URL="${DSH_PUBLIC_URL-http://localhost:${DSH_PORT}}"
# DSH rejects wildcard hosts. Pick the container/pod's first non-loopback IPv4.
if [ -z "$DSH_HOST" ]; then
DSH_HOST="$(node -e 'const os=require("os"); const ifaces=Object.values(os.networkInterfaces()).flat(); const addr=ifaces.find(v=>v&&v.family==="IPv4"&&!v.internal); if(!addr){process.exit(1)} process.stdout.write(addr.address)')"
fi
if [ -n "$DSH_PUBLIC_URL" ]; then
set -- --public-url "$DSH_PUBLIC_URL" "$@"
fi
exec node /app/lib/bin.js web \
--no-open \
--host "$DSH_HOST" \
--port "$DSH_PORT" \
--trusted-host localhost \
--trusted-host 127.0.0.1 \
"$@"
EOF
RUN chmod 0755 /usr/local/bin/dsh-entrypoint
WORKDIR /workspace
USER node
EXPOSE 3080
VOLUME ["/home/node/.dsh"]
STOPSIGNAL SIGTERM
ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/dsh-entrypoint"]
```
### What changed and why
| Area | Before | Now | Reason |
| ------ | -------- | ----- | -------- |
| Deploy linker | default isolated `.pnpm` store | `--config.node-linker=hoisted` | Produces a flat npm-style tree so peer deps like `@deepseek-ai/cosmokit` are physically present. |
| Deploy flag | `--legacy` | removed | Legacy deployer does not reliably bind peer dependencies; the modern deployer does. |
| Workspace binding | implicit | `--config.inject-workspace-packages=true` | Guarantees workspace packages and their peers are bound into the closure deterministically. |
| Missing peer patch | `@deepseek-ai/cordis-plugin-group@^1.0.1` | `@deepseek-ai/cordis-plugin-group@workspace:*` | Correct protocol for a monorepo-internal package; no dependency on a published npm version. |
| Verification | only `bin.js` exists + `web --help` | also asserts `cosmokit` and `cordis-plugin-group` directories exist | Fails the build early if the closure is still incomplete, instead of failing at container start. |
### Build and run
```bash
docker build \
--build-arg DSH_VERSION=dsh-v0.2.1-rc.2 \
-t dsh-web:0.2.1-rc.2 .
docker run --rm -it \
-p 3080:3080 \
-v dsh-home:/home/node/.dsh \
-e DEEPSEEK_API_KEY \
dsh-web:0.2.1-rc.2
```
Then open the `dsh web:` URL printed in the logs (it carries a per-process access token).
### If the `pnpm add …@workspace:*` step ever fails
That would mean `@deepseek-ai/cordis-plugin-group` is not a workspace package in the chosen tag. In that case remove the two `pnpm --filter … add` lines; the hoisted linker alone is usually sufficient to include peer dependencies. You can confirm by checking that the `test -d /opt/dsh/node_modules/@deepseek-ai/cordis-plugin-group` assertion still passes.