Skip to main content
A training image holds CUDA, Python, and whatever your train.sh imports. That is all.
Do not pip-install the StarForge CLI into the image, and do not copy observability code out of an old tutorial repository. The platform runtime is injected at launch as a content-addressed PEX — the image needs nothing for reporting to work.

What belongs in the image

Logs: print, logging, and framework stdout/stderr go to the console log tab. Do not POST /api/ingest/logs. Curves: not parsed from stdout. Call starforge.report from training code.

A starting Dockerfile

This matches the style of the platform TRL image: CUDA devel base, a venv on PATH, no StarForge package required if you will install the wheel in a later RUN (recommended for catalog custom/custom).
Adjust packages to what train.py imports. If you need DeepSpeed JIT compile, a devel image (nvcc) is the usual requirement, same as Dockerfile.trl. local executor runs the entrypoint with bash. PATH must still point at that venv so python inside train.sh is not /usr/bin/python without torch.

Build and push

Submit with a tag or a digest:

Allowlist

--image is parsed for a registry host (ghcr.io, localhost:5000, docker.io when the name has no host). That host must appear in the server list FORGE_ALLOWED_IMAGE_REGISTRIES (comma-separated hostnames in .env). Operators: set something like FORGE_ALLOWED_IMAGE_REGISTRIES=registry.example.com,ghcr.io. Nodes must be able to pull (KubeRay imagePullSecrets, agent Docker login, Slurm enroot/SIF already converted).

Executor notes

If pull is slow, the job sits in PENDING until the preRunning deadline, then FAILED. That is not a training bug.

Do not

  • COPY the StarForge source tree into /opt and hope it matches the server’s runner. The capsule is content-addressed and injected.
  • Bake HF_TOKEN into a layer. The server injects HF_TOKEN / HUGGING_FACE_HUB_TOKEN when configured, or a secrets file path (CLUSTER_SECRETS_FILE).
  • Point FORGE_INGEST_URL at 127.0.0.1 on the console host. Training nodes cannot use your laptop loopback. That variable is server-side; submitters do not set it, but empty charts with healthy stdout usually mean ops got it wrong.