#!/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"