# Native workload images The [Open WebUI compatibility image](openwebui/README.md) keeps completed chat responses intact across provider model-cache invalidation. Its pinned provider regressions and standalone build commands are described in that guide. The batch image (`services/metallo/Dockerfile.batch`) uses the target architecture for its checksum-pinned Git LFS binary. Builds accept `linux/amd64` and `linux/arm64`; another architecture fails before downloading a binary. The deployment image catalogue includes the application dependency lock in the batch fingerprint, so a dependency change rebuilds the deployed image. ## Offline application dependencies `application/uv.lock` pins Gradio, Streamlit and their dependencies for Python 3.14. The batch build downloads hashed native wheels into `/opt/pharos/wheels`. `PIP_NO_INDEX` and `PIP_FIND_LINKS` make the generated actions' existing `python -m pip install` commands use those wheels. The service init container installs them into the Attempt's private `/workspace/venv`; the application container uses the same virtual environment. UV receives the equivalent settings. This supports the pinned framework versions and their locked dependencies. Additional packages or other versions must be supplied as compatible wheels in the repository and installed with `--find-links`, or added to a reviewed platform image. A missing wheel fails installation without requiring public package egress. Existing Project network policies continue to apply. Update the source and lock together: ```sh uv lock --project devops/images/application docker build --platform linux/arm64 -f services/metallo/Dockerfile.batch . docker build --platform linux/amd64 -f services/metallo/Dockerfile.batch . ``` These commands use BuildKit's automatic `TARGETARCH` argument. With a legacy Docker builder, supply the matching `--build-arg TARGETARCH=amd64` or `arm64`. ## Hugging Face on ARM64 KServe 0.16.0's published Hugging Face image is AMD64 only. The qualification installer selects its pinned executable manifest on AMD64. On ARM64 it builds `huggingface/Dockerfile`, imports the native image and uses the imported digest in the owned namespaced ServingRuntime. The installed KServe controller selects that image; submitted InferenceServices retain their image-free model contract. The ARM image uses the unchanged KServe 0.16.0 Hugging Face source and vLLM 0.9.2 CPU source from checksum-pinned release archives. vLLM is needed by KServe's OpenAI protocol imports even with `--backend=huggingface`. Its native CPU extension is built with two compiler jobs. The Python 3.12 dependency lock includes ARM CPU PyTorch wheels and excludes the upstream image's Intel-only packages. Build-time checks validate dependency consistency and the actual server entry point. ```sh uv lock --project devops/images/huggingface docker build --platform linux/arm64 -f devops/images/huggingface/Dockerfile . ``` The image can also be published by Site administration and referenced by digest from its ServingRuntime. Building it does not install or alter a shared KServe controller, enable GPU inference or qualify other accelerators. Run `make metallo-site-api-services-test TARGET=dev-NAME` for real model prediction, both framework startups under restricted egress, and cancellation while workspace quota remains exhausted. This lane owns its namespaces and KServe installation; an existing KServe installation is preserved and causes an explicit refusal.