Quality gates / quality (pull_request) Successful in 3m29s
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
62 lines
2.3 KiB
Bash
Executable File
62 lines
2.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Run the pinned worker with the least privilege it can work under (issue #15).
|
|
#
|
|
# The worker is a private service. It is published on loopback only, mounts the verified weights
|
|
# read-only, keeps an immutable root filesystem, and holds no credential of any kind.
|
|
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)}"
|
|
PORT="${TIMMY_MODEL_PORT:-8080}"
|
|
PUBLISH_HOST="${TIMMY_WORKER_PUBLISH_HOST:-127.0.0.1}"
|
|
MODEL_DIR="${TIMMY_WORKER_MODEL_DIR:-${TIMMY_SELFHOST_ROOT:-$HOME/.local/share/timmy-selfhost}/models}"
|
|
NAME="${TIMMY_WORKER_CONTAINER:-timmy-vision-worker}"
|
|
ALIAS="${TIMMY_MODEL_ALIAS:-SmolVLM2-2.2B-Instruct}"
|
|
|
|
# Exposure is the one decision this recipe must never get wrong, so a non-loopback publish host is
|
|
# refused rather than warned about.
|
|
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
|
|
|
|
if [[ ! "$PORT" =~ ^[0-9]{1,5}$ ]] || (( PORT < 1 || PORT > 65535 )); then
|
|
printf 'Refusing to start: the port must be a number between 1 and 65535, got %s.\n' "$PORT" >&2
|
|
exit 64
|
|
fi
|
|
|
|
RUN_ARGS=(
|
|
run
|
|
--detach
|
|
--name "$NAME"
|
|
--read-only
|
|
--cap-drop=ALL
|
|
--security-opt no-new-privileges
|
|
--tmpfs /tmp:rw,noexec,nosuid,size=64m
|
|
--volume "$MODEL_DIR:/models:ro"
|
|
--publish "127.0.0.1:${PORT}:8080"
|
|
--env "TIMMY_MODEL_PORT=8080"
|
|
--env "TIMMY_MODEL_THREADS=${TIMMY_MODEL_THREADS:-4}"
|
|
"$IMAGE:$TAG"
|
|
)
|
|
|
|
if [[ "${1:-}" == '--print-plan' ]]; then
|
|
printf 'image: %s:%s\n' "$IMAGE" "$TAG"
|
|
printf 'model directory (read-only mount): %s\n' "$MODEL_DIR"
|
|
printf 'bind address: %s:%s\n' "$PUBLISH_HOST" "$PORT"
|
|
printf 'publish: %s:%s\n' "$PUBLISH_HOST" "$PORT"
|
|
printf 'health: %s ready (post-load gate)\n' "$ALIAS"
|
|
printf 'docker %s\n' "${RUN_ARGS[*]}"
|
|
exit 0
|
|
fi
|
|
|
|
if [[ ! -d "$MODEL_DIR" ]]; then
|
|
printf 'Refusing to start: %s is not a directory. Install the pinned weights with scripts/bootstrap_selfhost_smolvlm.sh install.\n' "$MODEL_DIR" >&2
|
|
exit 78
|
|
fi
|
|
|
|
docker "${RUN_ARGS[@]}"
|
|
printf 'Worker container %s started on %s:%s. Readiness: docker exec %s timmy-worker-ready\n' "$NAME" "$PUBLISH_HOST" "$PORT" "$NAME"
|