Skip to content

Provision a container image

You want the runtime present in an image so containers start without a first-run download.

Install it at build time

The estate's go-tools image does this. Fetch the archive, put the library on the loader's path, and name it:

ARG ONNXRUNTIME_VERSION=1.28.0
ARG ONNXRUNTIME_SHA256=a3e1b79d7bb1bf09696ce675f49e4064e6c81f6202b8225624fff0e93f8d6407

RUN curl -fsSL -o /tmp/ort.tgz \
      "https://gitlab.com/api/v4/projects/85407611/packages/generic/onnxruntime/${ONNXRUNTIME_VERSION}/onnxruntime-linux-x64-${ONNXRUNTIME_VERSION}.tgz" \
 && echo "${ONNXRUNTIME_SHA256}  /tmp/ort.tgz" | sha256sum -c - \
 && tar -xzf /tmp/ort.tgz -C /tmp \
 && cp -a /tmp/onnxruntime-linux-x64-${ONNXRUNTIME_VERSION}/lib/*.so* /usr/local/lib/ \
 && ldconfig \
 && rm -rf /tmp/ort.tgz /tmp/onnxruntime-linux-x64-${ONNXRUNTIME_VERSION}

ENV ONNXRUNTIME_LIB=/usr/local/lib/libonnxruntime.so

Two details that are easy to get wrong:

  • *.so*, not libonnxruntime.so*. The runtime needs libonnxruntime_providers_shared.so beside it, and the narrower glob silently leaves it behind — the failure appears later, as a provider that will not initialise.
  • A digest here, not in Go. A sha256sum -c in a Dockerfile is pinned to a build somebody reviewed, and the image is rebuilt when it changes. That is a different thing from a digest compiled into a binary, which cannot be rotated or revoked — see why there are no digests here.

Read it at run time

lib, err := resolver.Resolve(ctx, os.Getenv("ONNXRUNTIME_LIB"))

Inside the image the variable is set and the resolver returns it immediately. Outside, it is empty and the normal order applies, so one binary covers both.

In CI

Set the same variable in the job, and switch on any integration tests that depend on a real runtime:

variables:
  PHPBOTSCOUT_ORT_LIB: $ONNXRUNTIME_LIB
  INT_TEST_EMBED: "1"

Without this the embedding tests skip, and a suite that skips is a suite that reports green while testing nothing.