Spaces:
Running on Zero
Running on Zero
| # 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" | |