Skip to content

DIN Node

umeradl edited this page Jul 8, 2026 · 2 revisions

DIN Node

din-node is the containerized run path for DIN validators: it packages dincli — the trusted DIN host process — as a Docker image plus a Compose setup, so an operator can run a client, auditor, or aggregator without installing Python or dincli on the host. One docker compose up -d and the node is running; upgrades are git pull && docker compose up -d --build with all state preserved.

This is Phase 1 (Devnet Operator Baseline) of the validator-operations roadmap, and it is currently scoped for devnet.

Trusted control plane, untrusted execution

The design splits dincli's work into two trust domains:

  • Trusted control plane — runs inside din-node. Holds the wallet and config, talks to the chain and IPFS, and decides what to submit.
  • Untrusted execution — never runs inside din-node. Every training/scoring/aggregation job executes the model owner's Python code, which is treated as hostile. Each job runs in a short-lived, sandboxed Worker Node container.

Because din-node must be able to spawn those workers, the host's Docker socket is mounted into it (the image ships only the Docker client). Workers therefore launch as siblings of din-node on the host daemon, not nested inside it:

        Host Docker daemon  ◄──────── /var/run/docker.sock (mounted into din-node)
          │            │                       │
          ▼            ▼                 ┌──────┴─────┐
   ┌────────────┐ ┌────────────┐         │  din-node  │  dincli runs `docker run`
   │ din-worker │ │ din-worker │ ◄───────┤  (dincli)  │  → host daemon → sibling
   └────────────┘ └────────────┘         └────────────┘

⚠️ Security tradeoff: the mounted Docker socket gives din-node root-equivalent control of the host's Docker daemon — anyone who compromises din-node effectively owns the host. This is a deliberate devnet simplification, accepted and documented, not a solved problem. Don't run din-node next to unrelated sensitive workloads. Hardening options (rootless Docker, socket proxy, Podman) are future work. The worker sandbox itself is unaffected by this tradeoff.

State: one directory, bind-mounted at the same path

All persistent state lives in a single host directory, DIN_STATE_DIR, bind-mounted into the container at the identical absolute path:

$DIN_STATE_DIR/
├── config/dincli/            wallets/, config.json      ← your keys — back this up
├── cache/dincli/             manifests, models, job files (re-downloadable)
└── cache/dincli-worker/      worker pip packages (safe to delete, can be large)

The identical-path bind mount is load-bearing, not cosmetic: when dincli spawns a worker via the host daemon, the host resolves the volume paths — so the path dincli knows inside the container must also be valid on the host. (A named volume would silently give workers empty mounts — a known constraint of the Docker-outside-of-Docker pattern.)

Because state lives on the host, container rebuilds and image upgrades never touch the wallet, config, or caches. The container also runs as the operator's own UID/GID, so all files stay owned by the operator.

Operating it

cd dincli/docker/node
cp .env.example .env          # set DIN_STATE_DIR, DOCKER_GID, DIN_UID/DIN_GID
docker build -f ../worker/Dockerfile -t din-worker:dev ../../..   # pre-build worker image
docker compose up -d --build
docker compose exec din-node dincli system init                   # then configure as usual

Day-to-day, every dincli command runs through docker compose exec din-node dincli <args>; docker ps -a --filter "name=din-" shows the node plus any in-flight workers. Migrating from a host install is a straight copy of the platformdirs config/cache directories into DIN_STATE_DIR (documented step-by-step in the runbook).

din-node currently idles and is driven via exec, because dincli is a CLI, not yet a daemon. When the dind daemon lands (P4 roadmap), it becomes the container's main process — automating participation instead of waiting for commands. See DIN SDK for the shared layer that enables this.

Roadmap (validator operations)

Planned hardening on top of this baseline: HTTP /health endpoint for watchdog auto-restart, graceful SIGTERM handling (no state corruption on docker stop), structured JSON logging, and systemd/launchd service units.

Further reading

Clone this wiki locally