Skip to content

Deploy a Kronos worker with Docker

Deploy a yasp-embedded worker on a single host with docker run. For a Kubernetes cluster or fleet, use Deploy with Helm instead.

These steps run on the target machine (SSH in first) — or let the agent do it for you; see Kronos workers.

Set three values

Set your API key and mint a long-lived (about 6 months) registry key from it:

export YASP_API_KEY='yasp_...'
export REGISTRY_KEY=$(yasp-toolkit registry key)
export REGISTRY_KEY=$(curl -fsS -X POST \
  -H "Authorization: Bearer $YASP_API_KEY" -G \
  --data-urlencode "audience=nexus-api" \
  --data-urlencode "scope=nexus-read" \
  "https://compile.yasp.ai/api/token")

Store a Kronos (embedded) long-lived worker register key (~6 months) so the worker can register.

export KRONOS_WORKER_KEY=$(yasp-toolkit embedded key)
export KRONOS_WORKER_KEY=$(curl -fsS -X POST \
  -H "Authorization: Bearer $YASP_API_KEY" -G \
  --data-urlencode "audience=embedded-api" \
  --data-urlencode "scope=embedded-register" \
  "https://compile.yasp.ai/api/token")

Alternatively, you can continue to use your API key:

export KRONOS_WORKER_KEY="$YASP_API_KEY"

Then set the arch_spec you picked in Step 1:

export ARCH_SPEC=u2404-cu129-trt1014-py311       # the arch-spec from Step 1

Paste the block for your hardware

Pick the tab for your box — Jetson for any Tegra module (Orin NX/AGX/Nano), dGPU for a discrete card, Drive AGX for DriveOS. Run its three blocks in order: pull the image, start the worker, then add the autoheal sidecar and confirm registration — no other edits needed.

1. Log in and pull the image

echo "$REGISTRY_KEY" | docker login docker.yasp.ai -u token --password-stdin

export TAG=$(curl -fsS -u token:"$REGISTRY_KEY" \
  "https://docker.yasp.ai/v2/yasp-inference/backend/$ARCH_SPEC/tags/list" \
  | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -1)
export IMAGE=docker.yasp.ai/yasp-inference/backend/$ARCH_SPEC:$TAG
docker pull "$IMAGE"

2. Start the worker

docker run --detach \
  --name embedded_prod \
  --restart unless-stopped \
  --runtime nvidia \
  --label autoheal=true \
  --health-cmd "yasp-embedded health live" \
  --health-interval=30s --health-timeout=5s --health-retries=3 --health-start-period=60s \
  -e NVIDIA_VISIBLE_DEVICES=all \
  --group-add "$(stat -c %g /var/run/docker.sock)" \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e YASP_API_KEY=$KRONOS_WORKER_KEY \
  -e YASP_LAUNCH_WORKER_IMAGE=$IMAGE \
  -e YASP_LAUNCH_DOCKER_RUNTIME=nvidia \
  -e YASP_LAUNCH_DOCKER_SHM_SIZE=8g \
  -e YASP_LAUNCH_DOCKER_VOLUMES=yasp-dataset-cache:/mnt/dataset-cache \
  -e YASP_DATASET_CACHE_DIR=/mnt/dataset-cache \
  -e YASP_LAUNCH_DOCKER_FORWARD_ENV=YASP_DATASET_CACHE_DIR \
  $IMAGE \
  yasp-embedded register \
    --tag host=$(hostname -s) --tag version=$TAG --tag last_update=$(date +%F)

3. Add the autoheal sidecar and confirm registration

docker ps --filter name=^autoheal$ --format '{{.Names}}' | grep -q autoheal \
  || docker run --detach --name autoheal --restart always \
       -e AUTOHEAL_DEFAULT_STOP_TIMEOUT=30 \
       -v /var/run/docker.sock:/var/run/docker.sock willfarrell/autoheal

docker logs embedded_prod 2>&1 | grep -iE 'API Key OK|worker_registered'

1. Log in and pull the image

echo "$REGISTRY_KEY" | docker login docker.yasp.ai -u token --password-stdin

export TAG=$(curl -fsS -u token:"$REGISTRY_KEY" \
  "https://docker.yasp.ai/v2/yasp-inference/backend/$ARCH_SPEC/tags/list" \
  | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -1)
export IMAGE=docker.yasp.ai/yasp-inference/backend/$ARCH_SPEC:$TAG
docker pull "$IMAGE"

2. Start the worker

docker run --detach \
  --name embedded_prod \
  --restart unless-stopped \
  --runtime nvidia \
  --label autoheal=true \
  --health-cmd "yasp-embedded health live" \
  --health-interval=30s --health-timeout=5s --health-retries=3 --health-start-period=60s \
  -e NVIDIA_VISIBLE_DEVICES=all \
  --group-add "$(stat -c %g /var/run/docker.sock)" \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e YASP_API_KEY=$KRONOS_WORKER_KEY \
  -e YASP_LAUNCH_WORKER_IMAGE=$IMAGE \
  -e YASP_LAUNCH_DOCKER_GPUS=all \
  -e YASP_LAUNCH_DOCKER_SHM_SIZE=8g \
  -e YASP_LAUNCH_DOCKER_VOLUMES=yasp-dataset-cache:/mnt/dataset-cache \
  -e YASP_DATASET_CACHE_DIR=/mnt/dataset-cache \
  -e YASP_LAUNCH_DOCKER_FORWARD_ENV=YASP_DATASET_CACHE_DIR \
  $IMAGE \
  yasp-embedded register \
    --tag host=$(hostname -s) --tag version=$TAG --tag last_update=$(date +%F)

3. Add the autoheal sidecar and confirm registration

docker ps --filter name=^autoheal$ --format '{{.Names}}' | grep -q autoheal \
  || docker run --detach --name autoheal --restart always \
       -e AUTOHEAL_DEFAULT_STOP_TIMEOUT=30 \
       -v /var/run/docker.sock:/var/run/docker.sock willfarrell/autoheal

docker logs embedded_prod 2>&1 | grep -iE 'API Key OK|worker_registered'

Drive AGX is veth-less, so the worker runs on host networking, privileged, as root, with the host's TensorRT mounted in. Autoheal gets --network none (it only needs the socket).

1. Log in and pull the image

echo "$REGISTRY_KEY" | docker login docker.yasp.ai -u token --password-stdin

export TAG=$(curl -fsS -u token:"$REGISTRY_KEY" \
  "https://docker.yasp.ai/v2/yasp-inference/backend/$ARCH_SPEC/tags/list" \
  | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -1)
export IMAGE=docker.yasp.ai/yasp-inference/backend/$ARCH_SPEC:$TAG
docker pull "$IMAGE"

2. Start the worker

docker run --detach \
  --name embedded_prod \
  --restart unless-stopped \
  --runtime nvidia \
  --gpus all \
  --privileged --user root \
  --network=host \
  --label autoheal=true \
  --health-cmd "yasp-embedded health live" \
  --health-interval=30s --health-timeout=5s --health-retries=3 --health-start-period=60s \
  -e NVIDIA_VISIBLE_DEVICES=all \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /usr/src/tensorrt:/usr/src/tensorrt:ro \
  -e TENSORRT_ROOT=/usr/src/tensorrt/include \
  -e YASP_API_KEY=$KRONOS_WORKER_KEY \
  -e YASP_LAUNCH_WORKER_IMAGE=$IMAGE \
  -e YASP_LAUNCH_DOCKER_RUNTIME=nvidia \
  -e YASP_LAUNCH_DOCKER_GPUS=all \
  -e YASP_LAUNCH_DOCKER_NETWORK=host \
  -e YASP_LAUNCH_DOCKER_PRIVILEGED=true \
  -e YASP_LAUNCH_DOCKER_USER=root \
  -e YASP_LAUNCH_DOCKER_SHM_SIZE=8g \
  -e YASP_LAUNCH_DOCKER_VOLUMES=yasp-dataset-cache:/mnt/dataset-cache,/usr/src/tensorrt:/usr/src/tensorrt:ro \
  -e YASP_DATASET_CACHE_DIR=/mnt/dataset-cache \
  -e YASP_LAUNCH_DOCKER_FORWARD_ENV=YASP_DATASET_CACHE_DIR,TENSORRT_ROOT \
  $IMAGE \
  yasp-embedded register \
    --tag host=$(hostname -s) --tag version=$TAG --tag last_update=$(date +%F)

3. Add the autoheal sidecar and confirm registration

docker ps --filter name=^autoheal$ --format '{{.Names}}' | grep -q autoheal \
  || docker run --detach --name autoheal --restart always --network none \
       -e AUTOHEAL_DEFAULT_STOP_TIMEOUT=30 \
       -v /var/run/docker.sock:/var/run/docker.sock willfarrell/autoheal

docker logs embedded_prod 2>&1 | grep -iE 'API Key OK|worker_registered'

A line like worker_registered confirms it's up. The worker's advertised arch_spec (shown by yasp-toolkit embedded workers on your reference machine) is what you pass to --arch-spec when you compile.

Image arch_spec ≠ advertised arch_spec

The string in the image path is not what the worker advertises. On registration it prepends the CPU and detected GPU arch — e.g. image u2404-cu129-trt1014-py311 registers as amd64-sm120-u2404-cu129-trt1014. Always copy the advertised value from embedded workers, not the image name.

Worker not showing up?

Run docker logs embedded_prod and send the output to support@yasp.ai. Need an image for hardware that isn't listed? See requesting an arch_spec.

What the block does, and why
  • Registry key — minted from your API key via curl (no yasp-toolkit needed) and used as the docker login password (username token). Valid ~6 months.
  • $TAG — the newest published image for your arch_spec, read from the registry's tag list.
  • --group-add $(stat …) (Jetson/dGPU) — the docker socket's group id. The worker runs as non-root yasp but the socket is owned root:docker; without it the worker can't spawn the per-task compile containers and the first compile fails. (Drive AGX runs as --user root, which already reaches the socket — so it's dropped there.)
  • GPU flags — dGPU uses YASP_LAUNCH_DOCKER_GPUS=all; Jetson uses YASP_LAUNCH_DOCKER_RUNTIME=nvidia (its toolkit's csv mode rejects --gpus); Drive AGX needs both plus --gpus all on the worker for CUDA injection.
  • Drive AGX extras — it's veth-less (NVIDIA's nvethernet driver), so bridge networking fails and everything uses --network=host; --privileged lets the worker read /proc/device-tree/model to detect its arch_spec; --user root is needed for trtexec to init CUDA; and -v /usr/src/tensorrt + TENSORRT_ROOT provide the TRT headers the compile's CMake step needs (the image ships none).
  • --health-cmd + --label autoheal=true + the autoheal sidecar--restart unless-stopped only fires on process exit, not on unhealthy; the sidecar restarts the worker when its liveness check goes stale.
  • --tag host=… — lets you target this box later; see Tags & routing. The YASP_LAUNCH_DOCKER_* vars shape the per-task compile containers — full set in the Launcher reference.

Upgrade, stop, or remove

Re-run the three blocks to upgrade — docker pull fetches the newest image and docker run recreates the container. To stop or remove it:

docker stop embedded_prod   # pause (docker start embedded_prod to resume)
docker rm -f embedded_prod  # remove entirely (add: docker rm -f autoheal)