Sync upstream and build images / sync-and-build (push) Successful in 2m35s
- CI plan: candidates are npm latest AND next (release candidates), plus an
optional workflow_dispatch 'version' input for any exact version. This is
what was holding back 0.1.5-rc.2 (published as next, not latest).
- Upstream dsh-v* tags are no longer mirrored into this repo (deleted the
existing ones); master stays an exact branch mirror and every release links
to its upstream tag. This repo's tags are now exclusively v<image tag>.
- Dockerfile: build-provenance labels (org.opencontainers.image.revision /
.created, dev.milesward.ci-run) so releases cite the commit and CI run that
actually built the image instead of whatever HEAD is at publish time.
- Releases: shell template replaced by .gitea/scripts/publish-releases.js,
run on the node:22 base image (no runner deps). It pulls the upstream
GitHub release's English notes, adds version-dependent caveats (launch
token from 0.1.2, Session format V3 from 0.1.5), image facts and Unraid
deploy steps. Existing v* tags re-pointed to 2d033c3 (the commit that
built those images); their releases are regenerated in this format.
- README: dynamic badges (shields Gitea release, Gitea workflow status),
0.1.5-rc.2 row, pipeline/tag-namespace docs updated.
Co-Authored-By: Claude Fable 5 <[email protected]>
84 lines
3.9 KiB
Docker
84 lines
3.9 KiB
Docker
# Trusted container build of DeepSeek Harness (dsh).
|
|
#
|
|
# Upstream (https://github.com/deepseek-ai/deepseek-harness) publishes no
|
|
# official container image — only the @deepseek-ai/dsh npm package, released
|
|
# from the tagged source mirrored in this repository's `master` branch. This
|
|
# image installs that exact pinned release from registry.npmjs.org, so its
|
|
# provenance chain is: upstream tag -> upstream npm release -> this Dockerfile.
|
|
#
|
|
# No upstream code is patched. The all-interfaces bind goes through upstream's
|
|
# supported `--patch` launcher layer (/opt/deepseek-harness/web.cordis.patch.yml);
|
|
# the UI is only reachable through ports you explicitly publish on the host.
|
|
|
|
FROM node:22-bookworm-slim
|
|
|
|
# DSH_VERSION default is the pinned, known-good deployment version: 0.1.2+
|
|
# introduced launch-token auth and the @Remote gateway (breaks lanmode).
|
|
# Moving off it is a deliberate template edit, never a side effect of CI.
|
|
ARG DSH_VERSION=0.1.1-rc.2
|
|
# pnpm is required on PATH by dsh's plugin manager (`dsh plugin --profile web
|
|
# add|update|remove`). CI passes the current release; the scheduled freshness
|
|
# check rebuilds a -rN revision tag when a newer pnpm or base image ships.
|
|
ARG PNPM_VERSION=12.3.4
|
|
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends ca-certificates git \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# pnpm is a fixed npm global rather than a corepack shim: corepack resolves
|
|
# versions at runtime and can attempt downloads/writes outside the state
|
|
# volume (its cache is root-owned), which breaks the non-root uid-1000 /
|
|
# read-only-rootfs contract. A pinned global install is deterministic,
|
|
# offline, and readable by uid 1000.
|
|
RUN npm install -g "@deepseek-ai/dsh@${DSH_VERSION}" "pnpm@${PNPM_VERSION}" \
|
|
&& npm cache clean --force
|
|
|
|
COPY web.cordis.patch.yml /opt/deepseek-harness/web.cordis.patch.yml
|
|
|
|
# /workspace: the agent's working directory (mount your project here);
|
|
# /home/node/.dsh: dsh state (settings, credentials, sessions, plugins).
|
|
RUN mkdir -p /workspace /home/node/.dsh \
|
|
&& chown node:node /workspace /home/node/.dsh
|
|
|
|
# Everything writable at runtime (dsh state, pnpm store/cache for plugin
|
|
# installs) lives inside the mounted state volume, never the rootfs.
|
|
ENV DSH_HOME=/home/node/.dsh \
|
|
PNPM_HOME=/home/node/.dsh/.pnpm \
|
|
XDG_CACHE_HOME=/home/node/.dsh/.cache \
|
|
XDG_STATE_HOME=/home/node/.dsh/.state
|
|
|
|
EXPOSE 3080
|
|
|
|
USER node
|
|
WORKDIR /workspace
|
|
|
|
ARG DSH_VERSION
|
|
ARG PNPM_VERSION
|
|
# BASE_DIGEST: resolved digest of the FROM image at build time; the scheduled
|
|
# freshness check compares it (and pnpm-version) against current releases.
|
|
# GIT_SHA / CI_RUN / BUILD_DATE: build provenance, read back by the release
|
|
# publisher so each release points at the commit that actually built it.
|
|
ARG BASE_DIGEST=""
|
|
ARG GIT_SHA=""
|
|
ARG CI_RUN=""
|
|
ARG BUILD_DATE=""
|
|
LABEL org.opencontainers.image.title="deepseek-harness" \
|
|
org.opencontainers.image.description="DeepSeek Harness (dsh) web UI, built from the official npm release" \
|
|
org.opencontainers.image.version="${DSH_VERSION}" \
|
|
org.opencontainers.image.revision="${GIT_SHA}" \
|
|
org.opencontainers.image.created="${BUILD_DATE}" \
|
|
org.opencontainers.image.source="https://gitea.milesward.dev/mward4/deepseek-harness" \
|
|
org.opencontainers.image.url="https://github.com/deepseek-ai/deepseek-harness" \
|
|
org.opencontainers.image.licenses="MIT" \
|
|
dev.milesward.dsh-version="${DSH_VERSION}" \
|
|
dev.milesward.pnpm-version="${PNPM_VERSION}" \
|
|
dev.milesward.base-digest="${BASE_DIGEST}" \
|
|
dev.milesward.ci-run="${CI_RUN}"
|
|
|
|
ENTRYPOINT ["dsh"]
|
|
# --patch must come immediately after `web` (launcher flag), --no-open so a
|
|
# headless server never launches a browser (on 0.1.2+ an in-container browser
|
|
# could consume the one-time launch token). Unraid Post Arguments REPLACE this
|
|
# CMD entirely — operators must repeat the patch flag and --no-open.
|
|
CMD ["web", "--patch", "/opt/deepseek-harness/web.cordis.patch.yml", "--no-open"]
|