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.29.0
ARG ONNXRUNTIME_SHA256=c3fddc4f139a045b0c4902c57410f0694f1c2fdf9b6939fbe38b1aeae7cd14ba

RUN curl -fsSL -o /tmp/ort.tgz \
      "https://artifacts.phpboyscout.uk/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 (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

Give the job the library's path, and switch on any integration tests that depend on a real runtime:

variables:
  PHPBOTSCOUT_ORT_LIB: "/usr/local/lib/libonnxruntime.so"
  INT_TEST_EMBED: "1"

Write the path out rather than $ONNXRUNTIME_LIB. The image sets that with ENV, and GitLab expands variables: from CI/CD variables only, so the reference never becomes the path. phpbotscout's pipeline does exactly this and says why beside it.

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