Files
Timmy 46f961668f
Quality gates / quality (pull_request) Successful in 3m29s
feat: pin the self-hosted worker container and gate readiness on the loaded model (#15)
A worker that answers /v1/models has not necessarily loaded its weights, so the app
was offering an AI control that could only fail after the upload. Readiness now
passes only once the pinned model is loaded, and the not-loaded state reaches manual
Bristol entry in one tap. Verified against the real pinned llama.cpp build: it serves
503 while loading and the gate reports the distinct not-loaded state.

Adds the reproducible container recipe (digest-pinned bases, pinned llama.cpp commit,
hash-verified read-only weights, unprivileged, loopback-only publish), one shared
post-load readiness gate used by the host bootstrap and the image healthcheck, and a
target-GPU benchmark that refuses to write a receipt it did not measure.

Refs #15
2026-10-13 08:20:21 +00:00

86 lines
3.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# Build the pinned Timmy worker image (issue #15).
#
# Every pin is checked before docker is invoked, so an unpinned or floating reference fails here
# rather than producing an image nobody can reproduce.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
RECEIPTS="$REPO_ROOT/deploy/worker/receipts.json"
IMAGE="${TIMMY_WORKER_IMAGE:-timmy-vision-worker}"
TAG="${TIMMY_WORKER_TAG:-$(date -u +%Y%m%d)}"
PUBLISH_HOST="${TIMMY_WORKER_PUBLISH_HOST:-127.0.0.1}"
PORT="${TIMMY_MODEL_PORT:-8080}"
receipt_field() {
python3 - "$RECEIPTS" "$1" <<'PY'
import json
import sys
document = json.load(open(sys.argv[1]))
value = document
for part in sys.argv[2].split('.'):
value = value[int(part)] if part.isdigit() else value[part]
print(value)
PY
}
# An explicit value still wins, but an empty one is treated as an invalid pin rather than a default.
LLAMA_CPP_COMMIT="${TIMMY_LLAMA_CPP_COMMIT-$(receipt_field llamaCpp.commit)}"
MODEL_SHA256="${TIMMY_MODEL_SHA256-$(receipt_field models.0.sha256)}"
MMPROJ_SHA256="${TIMMY_MMPROJ_SHA256-$(receipt_field models.1.sha256)}"
MODEL_FILE="$(receipt_field models.0.file)"
MMPROJ_FILE="$(receipt_field models.1.file)"
BUILD_BASE="$(receipt_field baseImages.build.reference)@$(receipt_field baseImages.build.digest)"
RUNTIME_BASE="$(receipt_field baseImages.runtime.reference)@$(receipt_field baseImages.runtime.digest)"
if [[ ! "$LLAMA_CPP_COMMIT" =~ ^[0-9a-f]{40}$ ]]; then
printf 'Refusing to build: the llama.cpp pin must be a 40-hex commit, got %s (floating refs are not reproducible).\n' "${LLAMA_CPP_COMMIT:-<empty>}" >&2
exit 64
fi
for pin in "$MODEL_SHA256" "$MMPROJ_SHA256"; do
if [[ ! "$pin" =~ ^[0-9a-f]{64}$ ]]; then
printf 'Refusing to build: every model hash must be a pinned sha256, got %s.\n' "${pin:-<empty>}" >&2
exit 64
fi
done
for base in "$BUILD_BASE" "$RUNTIME_BASE"; do
if [[ ! "$base" =~ @sha256:[0-9a-f]{64}$ ]]; then
printf 'Refusing to build: base images must be digest-pinned, got %s.\n' "$base" >&2
exit 64
fi
done
if [[ ! "$PUBLISH_HOST" =~ ^(127\.0\.0\.1|::1|localhost)$ ]]; then
printf 'Refusing to publish the worker outside loopback (127.0.0.1): got %s.\n' "$PUBLISH_HOST" >&2
exit 64
fi
print_plan() {
printf 'image: %s:%s\n' "$IMAGE" "$TAG"
printf 'llama.cpp commit: %s\n' "$LLAMA_CPP_COMMIT"
printf '%s sha256: %s\n' "$MODEL_FILE" "$MODEL_SHA256"
printf '%s sha256: %s\n' "$MMPROJ_FILE" "$MMPROJ_SHA256"
printf 'base image (build): %s\n' "$BUILD_BASE"
printf 'base image (runtime): %s\n' "$RUNTIME_BASE"
printf 'bind address: %s:%s\n' "$PUBLISH_HOST" "$PORT"
printf 'publish: %s:%s\n' "$PUBLISH_HOST" "$PORT"
printf 'docker build --file deploy/worker/Dockerfile --build-arg LLAMA_CPP_COMMIT=%s --build-arg MODEL_SHA256=%s --build-arg MMPROJ_SHA256=%s --tag %s:%s .\n' \
"$LLAMA_CPP_COMMIT" "$MODEL_SHA256" "$MMPROJ_SHA256" "$IMAGE" "$TAG"
}
if [[ "${1:-}" == '--print-plan' ]]; then
print_plan
exit 0
fi
print_plan
cd "$REPO_ROOT"
docker build \
--file deploy/worker/Dockerfile \
--build-arg "LLAMA_CPP_COMMIT=$LLAMA_CPP_COMMIT" \
--build-arg "MODEL_SHA256=$MODEL_SHA256" \
--build-arg "MMPROJ_SHA256=$MMPROJ_SHA256" \
--tag "$IMAGE:$TAG" \
.
printf 'Built %s:%s from pinned receipts. Run it with deploy/worker/run_worker_container.sh\n' "$IMAGE" "$TAG"