63 lines
3.0 KiB
Docker
63 lines
3.0 KiB
Docker
# LMCache payload image for the operator's code-payload injection.
|
|
#
|
|
# When an LMCacheEngine sets spec.injection.payloadImage, the mutating webhook
|
|
# (operator/internal/webhook/lmcache_pod_injector.go) stages this image into a
|
|
# vLLM pod: it ships the `lmcache` tree under /payload and, on start, copies it
|
|
# into a shared emptyDir that the vLLM container imports via
|
|
# PYTHONPATH=/lmcache-payload — overriding the lmcache baked into the vLLM image
|
|
# so the vLLM client and the LMCache engine server run one matched build.
|
|
#
|
|
# Webhook contract (keep in lockstep):
|
|
# - the tree lives under /payload;
|
|
# - the ENTRYPOINT copies /payload into $SHARED_DIR (the webhook sets
|
|
# SHARED_DIR=/lmcache-payload and mounts a RW emptyDir there);
|
|
# - no command override — one makes the webhook skip staging.
|
|
#
|
|
# lmcache ships COMPILED extensions (.so) tied to a Python minor + torch/CUDA
|
|
# ABI, so this image EXTRACTS the already-built lmcache from a source image
|
|
# rather than recompiling. Set SOURCE_IMAGE to your vLLM image (or an
|
|
# ABI-compatible one).
|
|
#
|
|
# Build:
|
|
# docker build -f docker/Dockerfile.payload \
|
|
# --build-arg SOURCE_IMAGE=lmcache/vllm-openai:latest-nightly \
|
|
# -t <registry>/lmcache-payload:latest-nightly .
|
|
#
|
|
# Smoke test:
|
|
# docker run --rm -e SHARED_DIR=/out -v "$PWD/out:/out" <registry>/lmcache-payload:...
|
|
# test -f out/lmcache/__init__.py
|
|
|
|
# The image whose installed lmcache tree is extracted into the payload. Its
|
|
# Python/torch/CUDA ABI must match the vLLM pods that will import the payload.
|
|
ARG SOURCE_IMAGE=lmcache/vllm-openai:latest-nightly
|
|
|
|
#################### EXTRACT ####################
|
|
# Pull the installed `lmcache` package (and its dist-info, for version metadata)
|
|
# out of the source image into /payload. The location is resolved from the
|
|
# running interpreter so it tracks whatever site-packages / venv the image uses.
|
|
FROM ${SOURCE_IMAGE} AS extract
|
|
|
|
RUN set -eux; \
|
|
SITE="$(python3 -c 'import os, lmcache; print(os.path.dirname(os.path.dirname(os.path.abspath(lmcache.__file__))))')"; \
|
|
test -f "$SITE/lmcache/__init__.py"; \
|
|
mkdir -p /payload; \
|
|
for d in "$SITE"/lmcache "$SITE"/lmcache-*.dist-info; do \
|
|
[ -e "$d" ] && cp -a "$d" /payload/; \
|
|
done; \
|
|
test -f /payload/lmcache/__init__.py; \
|
|
python3 -c 'import lmcache; print("payload lmcache:", getattr(lmcache, "__version__", "unknown"))'
|
|
|
|
#################### PAYLOAD ####################
|
|
# Minimal image whose only job is to copy /payload into the injected emptyDir.
|
|
# busybox provides `cp -a`; SHARED_DIR is supplied at run time by the webhook
|
|
# (defaulted here only so a standalone `docker run -e SHARED_DIR=...` works).
|
|
FROM busybox:1.37
|
|
|
|
COPY --from=extract /payload /payload
|
|
|
|
ENV SHARED_DIR=/lmcache-payload
|
|
|
|
# `cp -a /payload/.` copies the tree CONTENTS (so $SHARED_DIR/lmcache/... lands
|
|
# directly on PYTHONPATH). `${SHARED_DIR:?}` fails loudly if the env is missing.
|
|
ENTRYPOINT ["/bin/sh", "-c", "set -eux; mkdir -p \"${SHARED_DIR:?SHARED_DIR must be set}\"; cp -a /payload/. \"${SHARED_DIR}/\""]
|