movimento / cloud-run /deploy.sh
rydlrKE's picture
Cloud Run encoder wiring + startup resilience
7939f87 verified
#!/usr/bin/env bash
# Deploy kimodo Cloud Run services.
# Usage:
# REGION=europe-west1 PROJECT_ID=my-project ./cloud-run/deploy.sh
# REGION=europe-west1 PROJECT_ID=my-project ALLOW_UNAUTHENTICATED=false ./cloud-run/deploy.sh
# REGION=europe-west1 PROJECT_ID=my-project GPU_TYPE=nvidia-h200-141gb GPU_COUNT=1 ./cloud-run/deploy.sh
set -euo pipefail
: "${REGION:?Set REGION (e.g. us-central1)}"
: "${PROJECT_ID:?Set PROJECT_ID}"
HF_SECRET_NAME="${HF_SECRET_NAME:-hf-token}"
ALLOW_UNAUTHENTICATED="${ALLOW_UNAUTHENTICATED:-true}"
GPU_TYPE="${GPU_TYPE:-nvidia-l4}"
GPU_COUNT="${GPU_COUNT:-1}"
IMAGE_TAG="$REGION-docker.pkg.dev/$PROJECT_ID/kimodo/kimodo:latest"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
GCLOUD_BIN="${GCLOUD_BIN:-}"
if [[ -z "$GCLOUD_BIN" ]]; then
if command -v gcloud >/dev/null 2>&1; then
GCLOUD_BIN="$(command -v gcloud)"
elif [[ -x "/workspaces/kimodo/.tools/google-cloud-sdk/bin/gcloud" ]]; then
GCLOUD_BIN="/workspaces/kimodo/.tools/google-cloud-sdk/bin/gcloud"
else
echo "gcloud not found. Set GCLOUD_BIN or install gcloud CLI."
exit 1
fi
fi
# ── Substitute image path into manifests ────────────────────────────────────
IMAGE_DIGEST=$("$GCLOUD_BIN" artifacts docker images list "$REGION-docker.pkg.dev/$PROJECT_ID/kimodo/kimodo" \
--include-tags \
--filter="tags:latest" \
--format="value(version)" \
--limit=1)
if [[ -z "$IMAGE_DIGEST" ]]; then
echo "Could not resolve digest for image tag: $IMAGE_TAG"
exit 1
fi
IMAGE="$REGION-docker.pkg.dev/$PROJECT_ID/kimodo/kimodo@$IMAGE_DIGEST"
echo "Deploying image: $IMAGE"
echo "Auth policy (allUsers invoker): $ALLOW_UNAUTHENTICATED"
echo "GPU profile: type=$GPU_TYPE count=$GPU_COUNT"
sed \
-e "s|REGION-docker.pkg.dev/PROJECT_ID/kimodo/kimodo:latest|$IMAGE|g" \
-e "s|HF_TOKEN_SECRET_NAME|$HF_SECRET_NAME|g" \
-e "s|GPU_TYPE_PLACEHOLDER|$GPU_TYPE|g" \
-e "s|GPU_COUNT_PLACEHOLDER|$GPU_COUNT|g" \
"$SCRIPT_DIR/text-encoder.yaml" > /tmp/text-encoder-rendered.yaml
sed \
-e "s|REGION-docker.pkg.dev/PROJECT_ID/kimodo/kimodo:latest|$IMAGE|g" \
-e "s|HF_TOKEN_SECRET_NAME|$HF_SECRET_NAME|g" \
-e "s|GPU_TYPE_PLACEHOLDER|$GPU_TYPE|g" \
-e "s|GPU_COUNT_PLACEHOLDER|$GPU_COUNT|g" \
"$SCRIPT_DIR/demo.yaml" > /tmp/demo-rendered.yaml
if grep -q 'HF_TOKEN_SECRET_NAME' /tmp/text-encoder-rendered.yaml; then
echo "Secret placeholder HF_TOKEN_SECRET_NAME still present in rendered text-encoder manifest"
exit 1
fi
if grep -q 'GPU_TYPE_PLACEHOLDER\|GPU_COUNT_PLACEHOLDER' /tmp/text-encoder-rendered.yaml; then
echo "GPU placeholders still present in rendered text-encoder manifest"
exit 1
fi
if grep -q 'GPU_TYPE_PLACEHOLDER\|GPU_COUNT_PLACEHOLDER' /tmp/demo-rendered.yaml; then
echo "GPU placeholders still present in rendered demo manifest"
exit 1
fi
if grep -q 'HF_TOKEN_SECRET_NAME' /tmp/demo-rendered.yaml; then
echo "Secret placeholder HF_TOKEN_SECRET_NAME still present in rendered demo manifest"
exit 1
fi
# ── 1. Deploy text-encoder ───────────────────────────────────────────────────
echo "Deploying movimento-text-encoder to $REGION..."
"$GCLOUD_BIN" run services replace /tmp/text-encoder-rendered.yaml \
--region "$REGION" \
--project "$PROJECT_ID"
if [[ "$ALLOW_UNAUTHENTICATED" == "true" ]]; then
"$GCLOUD_BIN" run services add-iam-policy-binding movimento-text-encoder \
--region "$REGION" \
--project "$PROJECT_ID" \
--member "allUsers" \
--role "roles/run.invoker" 2>/dev/null || true
fi
TEXT_ENCODER_URL=$("$GCLOUD_BIN" run services describe movimento-text-encoder \
--region "$REGION" \
--project "$PROJECT_ID" \
--format "value(status.url)")
echo "Text-encoder URL: $TEXT_ENCODER_URL"
if [[ -z "$TEXT_ENCODER_URL" ]]; then
echo "Text encoder URL is empty. Blocking downstream deployment."
exit 1
fi
echo "Running encoder health gate before deploying downstream services..."
PROJECT_ID="$PROJECT_ID" \
REGION="$REGION" \
SERVICE_NAME="movimento-text-encoder" \
HF_SECRET_NAME="$HF_SECRET_NAME" \
DEMO_SERVICE_NAME="kimodo-demo" \
"$SCRIPT_DIR/health_gate_text_encoder.sh"
# ── 2. Inject text-encoder URL into demo manifest and deploy ─────────────────
sed -i "s|TEXT_ENCODER_URL_PLACEHOLDER|$TEXT_ENCODER_URL/|g" /tmp/demo-rendered.yaml
if grep -q 'TEXT_ENCODER_URL_PLACEHOLDER' /tmp/demo-rendered.yaml; then
echo "TEXT_ENCODER_URL_PLACEHOLDER still present in demo manifest"
exit 1
fi
echo "Deploying kimodo-demo to $REGION..."
"$GCLOUD_BIN" run services replace /tmp/demo-rendered.yaml \
--region "$REGION" \
--project "$PROJECT_ID"
if [[ "$ALLOW_UNAUTHENTICATED" == "true" ]]; then
"$GCLOUD_BIN" run services add-iam-policy-binding kimodo-demo \
--region "$REGION" \
--project "$PROJECT_ID" \
--member "allUsers" \
--role "roles/run.invoker" 2>/dev/null || true
fi
DEMO_URL=$("$GCLOUD_BIN" run services describe kimodo-demo \
--region "$REGION" \
--project "$PROJECT_ID" \
--format "value(status.url)")
echo "Re-running encoder health gate to verify dependency contract after demo deploy..."
PROJECT_ID="$PROJECT_ID" \
REGION="$REGION" \
SERVICE_NAME="movimento-text-encoder" \
HF_SECRET_NAME="$HF_SECRET_NAME" \
DEMO_SERVICE_NAME="kimodo-demo" \
"$SCRIPT_DIR/health_gate_text_encoder.sh"
echo ""
echo "βœ“ Deployment complete."
echo " Text-encoder: $TEXT_ENCODER_URL"
echo " Demo UI: $DEMO_URL"