zkDeal engineering · Technology Brief

Run the supplied Docker stack—or customize any role

Start with zkDeal’s published Docker operating planes, inspect a digest-pinned CUDA prover, and learn where customization keeps the proof and settlement boundaries intact.

Oleg Iakushkin5 min read
DockerRISC ZeroCUDAOperations

DEPLOYABLE DOCKER ARCHITECTURE • READY-TO-RUN IMAGES

Run the supplied Docker stack—or customize any role

zkdeal supplies separate Docker images for live room execution, operations and validation. Teams can run the default topology, co-locate roles for a smaller deployment, or substitute individual components while preserving the selected room and settlement boundaries.

From an application request to Ethereum settlement

Explore the architecture

Deployable Docker architecture

Pan · zoom · select a node
Users + app services

configure rooms • sign transactions • read results • request withdrawals

Ethereum L1

RoomManager • RoomPool • RoomVault • forced inbox • verifiers • claims

zkdeal/coordinator

API • rooms • admissions • proof queue • index • reconcile • publish • auto-claim • active or standby roles

zkdeal/headless-room-node

join room • sequence • prepare batches • request proofs • verify • watch finality • checksummed room lifecycle state

L1 connections

two RPC views • scoped writer • L1 events and finality in • proof-backed checkpoints out

Application infrastructure

PostgreSQL • object storage • route • remote signer • room volume

Durable queue

proof jobs • leases • results

zkdeal/prover-agent

outbound pull • lease • feed • return

zkdeal/prover-cuda

GPU room • data • aggregate proof generation

zkdeal/operator-docs

guides • API • metrics

zkdeal/deployment-tools

deploy • inspect • conform

zkdeal/backup-tools

encrypted backup • restore

zkdeal/promotion-controller

verify promotion conditions

zkdeal/failover-provider

fence writer • switch route

zkdeal/acceptance-runner

end-to-end behavior

zkdeal/failover-runner

promotion + fencing drill

zkdeal/soak-runner

sustained restart-safe run

zkdeal/fault-control

restarts • partitions • reorgs

zkdeal/backup-restore-control

fresh-target restore checks

Solid arrows

live capital, requests, state or proofs

Dashed arrows

deployment, recovery or validation control

GPU boundary

The agent pulls jobs; the GPU host needs no public or control-plane inbound connection.

Mini Map

Drag the canvas to pan, use the wheel or pinch gesture to zoom, and use the controls to zoom or fit the whole model. Expand for a page-sized view; press Escape to close it.

Interactive architecture diagram.
View the static reference imagezkdeal deployment architecture. Users and app services send signed room requests to the coordinator and interact directly with Ethereum for deposits, claims and refunds. The coordinator works with a headless room node, durable storage and a pull-only proving lane made of prover-agent and prover-cuda. Ethereum L1 receives data and proof-backed checkpoints. Operator, deployment, backup, promotion and failover images support the live stack. Acceptance, failover, soak, fault-control and backup-restore images validate it on demand. Every role can be customized behind the same interfaces.
Read the figure transcript

zkdeal deployment architecture. Users and app services send signed room requests to the coordinator and interact directly with Ethereum for deposits, claims and refunds. The coordinator works with a headless room node, durable storage and a pull-only proving lane made of prover-agent and prover-cuda. Ethereum L1 receives data and proof-backed checkpoints. Operator, deployment, backup, promotion and failover images support the live stack. Acceptance, failover, soak, fault-control and backup-restore images validate it on demand. Every role can be customized behind the same interfaces.

Ready images by operating plane

RUN zkdeal/coordinator hosts the API and service roles; zkdeal/headless-room-node runs bounded room execution; zkdeal/prover-agent pulls proof work; zkdeal/prover-cuda generates room, data and aggregate proofs.

OPERATE + RECOVER zkdeal/operator-docs, zkdeal/deployment-tools and zkdeal/backup-tools support the deployment; zkdeal/promotion-controller and zkdeal/failover-provider verify a handoff, fence the old writer and switch the route.

VALIDATE + REHEARSE zkdeal/acceptance-runner, zkdeal/failover-runner, zkdeal/soak-runner, zkdeal/fault-control and zkdeal/backup-restore-control exercise normal operation, recovery, long runs, controlled faults and clean-target restore.

Customize by interface, then revalidate the chosen profile

Motivational example

Start with something you can run this afternoon

Suppose you want to know whether the prover really uses your GPU. The quickest useful answer is not another architecture diagram. Pull one immutable image, let Docker present the device, and ask the running service what it can do.

That small experiment also shows why the stack is split into roles. You can begin with zkDeal’s published prover, coordinator, room node, and recovery path, then replace one role when you have a reason to own it. The boundary is concrete: preserve the API, queue, proof format, storage, and Ethereum behavior required by the room profile, then run the same checks again.

  • Pull the B200-native sm100 prover by immutable digest.
  • Confirm native cubins, CUDA production mode, and disabled CPU and PTX fallbacks.
  • Keep the evaluation listener on loopback and keep identity fields out of copied logs.

Demo / use it today

Inspect a digest-pinned B200 prover

This smoke path checks four concrete things: the exact public image was selected, its executable carries native sm100 cubins, Docker can pass a B200 into it, and the running service reports a production CUDA build with CPU and PTX fallbacks disabled.

Before you start

  • A Bash-compatible shell: Linux, macOS, or WSL on Windows. The copyable commands use POSIX shell syntax.
  • Docker with the NVIDIA Container Toolkit and an NVIDIA B200 (compute capability 10.0).
  • OpenSSL for an unprinted temporary token, plus curl and jq for deliberately filtered readiness output.
  • A free loopback port 8080 and no other GPU compute container.
  1. Pin first

    The tutorial assigns the full architecture-specific digest to IMAGE. It never uses latest, and the pull output must repeat the same digest.

  2. Verify the hardware boundary

    The first disposable run asks NVIDIA for the model and compute capability. The next check inspects the executable for sm100 cubins before the service is allowed to prove with PTX JIT disabled.

  3. Inspect only safe fields

    The service routes include richer identity data. The jq projections intentionally omit GPU UUID, guest program identifiers, container telemetry labels, and any token.

Pin the public image

IMAGE=zkdeal/prover-cuda@sha256:e1a0b4b36637a415823fdcf1139657884dfa1f1016441a8d1e3701bed4483d67

Pull by digest

docker pull "$IMAGE"
Expected output shape
Digest: sha256:e1a0b4b36637a415823fdcf1139657884dfa1f1016441a8d1e3701bed4483d67
Status: Image is up to date for zkdeal/prover-cuda@sha256:e1a0b4b3…

Confirm the GPU architecture

docker run --rm --gpus all --entrypoint nvidia-smi "$IMAGE" \
  --query-gpu=name,compute_cap --format=csv,noheader
Expected output shape
NVIDIA B200, 10.0

Bind the image to its public source checkpoint

docker image inspect "$IMAGE" --format '{{json .Config.Labels}}' | jq -c \
  '{source:."org.opencontainers.image.source",revision:."org.opencontainers.image.revision",sourceManifest:."org.opencontainers.image.source-manifest.sha256"}'
Expected output shape
{"source":"https://github.com/zkdeal/zkdeal-prover","revision":"d60547ba7e040d2ba77bd154bb6e20c10d276657","sourceManifest":"7e14703e340e84aaca2af36224b6fb1e47ce0c2f64f2a88d9eb09d932800246f"}

Extract the prover binary without starting it

BIN_DIR="$(mktemp -d)" && CID="$(docker create "$IMAGE")" && \
  docker cp "$CID:/usr/local/bin/zkdeal-r0" "$BIN_DIR/zkdeal-r0" && \
  docker rm "$CID" >/dev/null

Require native sm100 cubins

docker run --rm -v "$BIN_DIR/zkdeal-r0:/tmp/zkdeal-r0:ro" \
  nvidia/cuda:12.9.1-devel-ubuntu22.04@sha256:38804006c937a83f28f63a959abcee688042072319c8614ad57b350958a30bd3 \
  cuobjdump -lelf /tmp/zkdeal-r0 | grep '\.sm_100\.cubin'
Expected output shape
ELF file    1: zkdeal-r0.1.sm_100.cubin
ELF file    2: zkdeal-r0.2.sm_100.cubin
ELF file    3: zkdeal-r0.3.sm_100.cubin
ELF file    4: zkdeal-r0.4.sm_100.cubin
ELF file    5: zkdeal-r0.5.sm_100.cubin

Generate a temporary token without printing it

export ZKDEAL_PROVER_TOKEN="$(openssl rand -hex 32)"

Start a loopback-only smoke service

PROVER_ID="$(docker run --rm --gpus all -d \
  -p 127.0.0.1:8080:8080 -e ZKDEAL_PROVER_TOKEN -e CUDA_DISABLE_PTX_JIT=1 \
  -e SEGMENT_PO2=20 "$IMAGE")" && export PROVER_ID

Read sanitized readiness

curl -fsS http://127.0.0.1:8080/healthz | \
  jq '{status,protocolVersion,evmFork,cpuFallback,prover}'
Expected output shape
{"status":"ready","protocolVersion":6,"evmFork":"osaka","cpuFallback":false,"prover":"risc0-local-cuda"}

Read sanitized capabilities

curl -fsS http://127.0.0.1:8080/v5/capabilities | \
  jq '{protocolVersion,backendId,cudaCompiled,productionCompiled,proofModes,ethereumSeal}'
Expected output shape
{"protocolVersion":6,"backendId":"risc0","cudaCompiled":true,"productionCompiled":true,"proofModes":["succinct","groth16"],"ethereumSeal":true}

Remove the disposable service

docker stop "$PROVER_ID" >/dev/null && rm -r -- "$BIN_DIR" && \
  unset PROVER_ID ZKDEAL_PROVER_TOKEN BIN_DIR CID

What this gives you: A native sm100 cubin list plus protocolVersion 6, cudaCompiled and productionCompiled true, and cpuFallback false is the minimum useful smoke signal. The companion Kurtosis run then completed its cold proof and checkpoint path on the same B200-native image.

Interactive validated I/O

Inspect the digest-pinned B200 prover

Validated on the B200 host

Select text directly in the player, pause at any point, or copy the complete transcript below.

Copy or read the complete transcript
$ IMAGE=zkdeal/prover-cuda@sha256:e1a0b4b36637a415823fdcf1139657884dfa1f1016441a8d1e3701bed4483d67
$ docker pull "$IMAGE"
Digest: sha256:e1a0b4b36637a415823fdcf1139657884dfa1f1016441a8d1e3701bed4483d67
Status: Image is up to date for zkdeal/prover-cuda@sha256:e1a0b4b3…
$ docker run --rm --gpus all --entrypoint nvidia-smi "$IMAGE" \
>   --query-gpu=name,compute_cap --format=csv,noheader
NVIDIA B200, 10.0
$ docker image inspect "$IMAGE" --format '{{json .Config.Labels}}' | jq -c \
>   '{source:."org.opencontainers.image.source",revision:."org.opencontainers.image.revision",sourceManifest:."org.opencontainers.image.source-manifest.sha256"}'
{"source":"https://github.com/zkdeal/zkdeal-prover","revision":"d60547ba7e040d2ba77bd154bb6e20c10d276657","sourceManifest":"7e14703e340e84aaca2af36224b6fb1e47ce0c2f64f2a88d9eb09d932800246f"}
$ BIN_DIR="$(mktemp -d)" && CID="$(docker create "$IMAGE")" && \
>   docker cp "$CID:/usr/local/bin/zkdeal-r0" "$BIN_DIR/zkdeal-r0" && \
>   docker rm "$CID" >/dev/null
$ docker run --rm -v "$BIN_DIR/zkdeal-r0:/tmp/zkdeal-r0:ro" \
>   nvidia/cuda:12.9.1-devel-ubuntu22.04@sha256:38804006c937a83f28f63a959abcee688042072319c8614ad57b350958a30bd3 \
>   cuobjdump -lelf /tmp/zkdeal-r0 | grep '\.sm_100\.cubin'
ELF file    1: zkdeal-r0.1.sm_100.cubin
ELF file    2: zkdeal-r0.2.sm_100.cubin
ELF file    3: zkdeal-r0.3.sm_100.cubin
ELF file    4: zkdeal-r0.4.sm_100.cubin
ELF file    5: zkdeal-r0.5.sm_100.cubin
$ export ZKDEAL_PROVER_TOKEN="$(openssl rand -hex 32)"
$ PROVER_ID="$(docker run --rm --gpus all -d \
>   -p 127.0.0.1:8080:8080 -e ZKDEAL_PROVER_TOKEN -e CUDA_DISABLE_PTX_JIT=1 \
>   -e SEGMENT_PO2=20 "$IMAGE")" && export PROVER_ID
$ curl -fsS http://127.0.0.1:8080/healthz | \
>   jq '{status,protocolVersion,evmFork,cpuFallback,prover}'
{"status":"ready","protocolVersion":6,"evmFork":"osaka","cpuFallback":false,"prover":"risc0-local-cuda"}
$ curl -fsS http://127.0.0.1:8080/v5/capabilities | \
>   jq '{protocolVersion,backendId,cudaCompiled,productionCompiled,proofModes,ethereumSeal}'
{"protocolVersion":6,"backendId":"risc0","cudaCompiled":true,"productionCompiled":true,"proofModes":["succinct","groth16"],"ethereumSeal":true}
$ docker stop "$PROVER_ID" >/dev/null && rm -r -- "$BIN_DIR" && \
>   unset PROVER_ID ZKDEAL_PROVER_TOKEN BIN_DIR CID
Video fallback generated with VHS 0.11.0

Pinned public inputs

Repositories and images used here

Current first-party zkdeal repositories and packages are MIT licensed. These pinned historical inputs retain the license recorded at each referenced commit or image digest.