docs/container-images.md

Run container images

Use the published container lane that matches your backend.

The project publishes one GHCR package with the lane in the tag. Every lane is a linux/amd64 + linux/arm64 manifest, so the same tag works on both.

TagMeaning
:<version>-cuda, -vulkan, or -cpuImmutable and never republished
:latest-cuda, -vulkan, or -cpuMoves to the newest release
:latestSelects the CPU lane, which works without an accelerator
:main-cuda, -vulkan, or -cpuMoves with main. The project rebuilds it after container infrastructure changes and on the nightly schedule. It is not a release.

The entrypoint is vllm-server, so flags go straight after the image name and the server keeps its own default of 0.0.0.0:8000:

docker run --rm -p 8000:8000 \
  -v /path/to/models:/models:ro \
  ghcr.io/mudler/vllm.cpp:latest \
  --model /models/Qwen3.6-35B-A3B

For the CUDA lane, the GPU driver comes from the host through the container runtime; the image carries only the CUDA runtime libraries it links:

docker run --rm --gpus all -p 8000:8000 \
  -v /path/to/models:/models:ro \
  ghcr.io/mudler/vllm.cpp:latest-cuda \
  --model /models/Qwen3.6-35B-A3B

/models is the weights mount and /cache is the tokenizer/HF cache. The container runs as UID 1000, so that user must be able to write to /cache and read the weights under /models. A model file with mode 0600 owned by another user fails as safetensors: cannot open file, which can look like a corrupt checkpoint rather than a permissions problem.

Pick the flags for your GPU#

The two NVIDIA families need different invocations. Both rows were verified on the listed hardware.

HostVerified onFlags
SBSA / datacenter arm64, x86_64GB10 sm_121a--gpus all
Jetson / Tegra (L4T)AGX Orin sm_87, L4T R36.4.3--runtime nvidia --gpus all

On Jetson, the runtime refuses --gpus all by itself (“invoking the NVIDIA Container Runtime Hook directly … is not supported”). Using only --runtime nvidia starts a container with no driver that dies on libcuda.so.1: cannot open shared object file, which looks like a broken image rather than a missing flag. Use both:

docker run --rm --runtime nvidia --gpus all -p 8000:8000 \
  -v /path/to/models:/models:ro \
  ghcr.io/mudler/vllm.cpp:latest-cuda \
  --model /models/Qwen3-0.6B

That exact recipe was run on an AGX Orin with Qwen/Qwen3-0.6B: the server serves /v1/completions and tegrastats shows GR3D_FREQ at 95-97% during generation, so decode is on the GPU.

If the server exits at startup#

SymptomCause
safetensors: cannot open fileUID 1000 cannot read the weights. A 0600 model owned by another user fails here and can look corrupt.
libcuda.so.1: cannot open shared object fileno driver in the container, on Jetson, add --gpus all alongside --runtime nvidia
--model <dir> is requiredthe server takes flags directly; everything after the image name goes to vllm-server

Point any OpenAI client base_url at the server:

from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")
print(client.completions.create(model="Qwen3.6-35B-A3B",
                                prompt="The capital of France is",
                                max_tokens=64).choices[0].text)