feat(docker): add din-node containerized run path for dincli#12
Conversation
Add a din-node container (dincli + docker CLI client) plus a Compose run path so operators can run dincli as a containerized host process instead of a local Python install. din-node holds wallet/config state and spawns the existing per-job din-worker containers as siblings via the mounted host docker.sock. - dincli/docker/node/Dockerfile: built install, docker-ce-cli (client only), non-root user, pinned Python/deps - dincli/docker/node/docker-compose.yml: socket mount + identical-path bind mount for CONFIG/CACHE/DOCKER_CACHE dirs - dincli/docker/node/.env.example: host UID/GID/state config - dincli/docker/node/README.md: operator runbook incl. docker.sock tradeoff - .dockerignore + .gitignore updates
…ss + doc status notes WS1 — README operator-completeness (3 gaps): - Add 'Migrating from a host install' section with idempotent copy commands targeting the three DIN_STATE_DIR paths and read-wallet verify step (with encrypted-wallet password-prompt caveat). - Add 'List DIN containers' to the Day-to-day lifecycle table with the anonymous-install caveat (name=din- filter misses it). - Add 'Cleaning up a stuck or orphaned worker' subsection covering stop/rm, bulk-clear of exited workers, and the warning that stopping a running worker kills the active job. WS2 — Doc-inaccuracy patches: - containerization.md: annotate Phase 1 (implemented), Phase 2 (already covered by all three roles), mount table (actual mounts differ from design — cite run_worker_container). - validator-operations.md: annotate Docker Compose gap (addressed by this PR) and Phase 1 doc item (covered by README).
PR Review — Santiago Rodriguez Cetran —
|
Follow-up review — closingSecond commit ( Gap 1 — Migration story ✅ Gap 2 — Container visibility ✅ Gap 3 — Orphaned worker cleanup ✅ Doc patches ✅ No new issues introduced. The README is now complete as an operator runbook: first-time setup, migration, day-to-day, state layout, stuck-worker recovery, troubleshooting, and scope/limitations all present. Merging. |
…rk-package table Replace WP-by-WP prose sections with a single 56-row table spanning P3 and P4, covering all domains: DevOps, Core Protocol, Security/Slashing, Cryptoeconomics, AI/Scoring, Testing/QA, Documentation, Operations, and Research. New items extracted from HR files, validator feedback, and discussion logs not previously captured in the roadmap: - P3-PR13: Robbert's PR #13 blockers tracked with explicit P3-6.1 dependency - P3-BUG1: stake nonce re-approval bug (validator-reported) - P3-BUG2: pyproject.toml Python version pin (flagged in PR #12) - P3-UX1: CLI onboarding friction (Filebase docs, uv support, burner wallet) - P3-SCR: BlockFLow scoring validation as standalone QA item - P3-DOC1: ARCHITECTURE.md (currently empty) explicitly tracked - P3-DOC7: dind architecture document as P4 daemon prerequisite - OPS-1/2/3: validator partner outreach, first-public-validator, grant proposal - RES-1/2: Filecoin migration and backdoor defense as deferred research - P4-IDX1/2/3: Robbert's on-chain indexer formally scheduled - P4-PROC: P3 retrospective + test suite investment Discussion section replaced with 5 concise, actionable notes covering DAO governance priority, BlockFLow vs Shapley decision, Filebase/Filecoin strategy, external validator operational requirements, and threat model scope. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
Adds a containerized
din-noderun path fordincli: a Docker image plus aCompose setup that lets operators run
dincliwithout installing Python locally.This is Phase 1: Devnet Operator Baseline of the validator-operations roadmap.
din-nodeis the trusted host process. It holds wallet/config state and usesthe host Docker daemon to spawn the existing per-job
din-worker:devcontainersas siblings. The worker sandbox itself is unchanged.
Changes
dincli/docker/node/Dockerfile— thedin-nodeimage.dincli/docker/node/docker-compose.yml— Docker socket mount + persistentbind-mounted state.
dincli/docker/node/.env.example— host-specific UID/GID/state config(operators copy it to
.env, which is git-ignored).dincli/docker/node/README.md— operator runbook..dockerignore— reduces the Docker build context..gitignore— ignore local virtualenvs (.venv*/).Design notes
dinclias a built, non-editable package (upgrade = rebuild theimage). The image installs the current source tree as a built package; current
package metadata is
0.1.0. Python pinned to3.12-slim.dincli/requirements.txt(exact==) for reproducibility.docker-ce-cli), not a daemon — it talks tothe host daemon over the mounted socket.
dinuser) by default, withgroup_add: ${DOCKER_GID}so itcan access
/var/run/docker.sock(DOCKER_GIDis host-specific:stat -c '%g' /var/run/docker.sock).DIN_STATE_DIR, not named volumes:worker containers are created by the host daemon, which resolves the
-vpath against the host filesystem. A named volume's data lives under Docker's
internal storage, not at the in-container path
dinclipasses, so the workerwould get an empty mount and fail silently. Bind-mounting one host dir at the
identical absolute path makes it valid from both views. (Confirmed with the lead.)
Volume layout (all under one host dir
DIN_STATE_DIR):config/dincliCONFIG_DIR(wallet/config)cache/dincliCACHE_DIR(manifests/models/jobs)cache/dincli-dockerDOCKER_CACHE_DIR(worker pkgs)Security tradeoff
din-nodemounts/var/run/docker.sock, which gives it root-equivalent controlof the host Docker daemon. This is intentional for the devnet baseline and
documented in the runbook. Untrusted worker job containers still run without
the socket, without wallet state, and with the existing sandbox constraints
(
--network none, read-only mounts, resource limits). One caveat surfaced whiledocumenting this: the dependency-install step (
pip installof the model owner'srequirements) runs in a networked container by necessity, and
pipcan runpackage build hooks — so install is not network-isolated (existing worker-layer
behaviour, out of scope to change here, flagged in the runbook). Operator
guidance: don't run
din-nodeon a host you don't trust the operator of.Verification
Tested on Docker 29.x:
din-nodeimage builds and runs as non-rootdinuser;dincliworks inside.din-nodereaches the host daemon (socket access works).a real
din-worker:devrun (--network none) that executed and wroteresult.json(output owned by the host user, not root).Doc inaccuracies found (per task §5)
containerization.md"Phase 1: Local Docker Worker Prototype" is written asfuture work, but the worker sandbox already exists in
worker.py. The onlyun-built Phase-1 item is the Compose/operator run path — this PR.
all three roles already call the worker layer.
/din/data,/din/logs; actual:/din/modelro,/din/job/job.jsonro,/din/outputrw,/din/packagesro).validator-operations.mdlists "no standard Docker Compose run path" — addressed here.dincli/cli/utils.pydocstrings reference~/.din/...; real paths are~/.config/dincli/...viaplatformdirs. Andpyproject.tomlrequires-python = ">=3.9"conflicts withpy-cid==0.5.0(>=3.10).With more time
Pin the base image by digest, add a startup check for
XDG_*/socket access, andrun a full
train-lmsagainst a local chain (the no-chain worker repro alreadyproves the spawn mechanism).