SPB Git

spb/ka2 Public

ka2 — explorateur structuré du web québécois (édition légère, Groupe KA). Bot scraper+IA → graphe de connaissances. Claude Haiku + Firecrawl/Scrapfly.

Python 98.1% Shell 1.9%
3.4 KB · 97 lines shellscript
Raw Blame History
1#!/usr/bin/env bash2# Author: Simon-Pierre Boucher3# Contact: contact@spboucher.ai4#5# Déploie ka2 sur un node macOS du cluster (défaut : M4M36) :6#   - venv + dépendances7#   - 3 services launchd résilients (KeepAlive) : web, bot long terme, tunnel ngrok8#   - tunnel ngrok --url=https://www.ka2.bot -> uvicorn 127.0.0.1:87999#10# Usage (depuis le laptop) :  bash deploy/deploy.sh [NODE] [PORT] [DOMAIN]11set -euo pipefail1213NODE="${1:-M4M36}"14PORT="${2:-8799}"15DOMAIN="${3:-www.ka2.bot}"16REMOTE_DIR="~/cluster-projects/ka2"17NGROK="/opt/homebrew/bin/ngrok"1819echo "==> Déploiement de ka2 sur ${NODE} (port ${PORT}, domaine ${DOMAIN})"2021# 1) Synchro du code (sans venv/db/git)22rsync -az --delete \23  --exclude '.venv' --exclude '.git' --exclude '*.db' --exclude '*.db-*' \24  --exclude '__pycache__' --exclude 'exports' \25  ./ "${NODE}:${REMOTE_DIR}/"2627# 2) Configuration distante (venv, deps, launchd)28ssh "${NODE}" DOMAIN="${DOMAIN}" PORT="${PORT}" NGROK="${NGROK}" 'bash -s' <<'REMOTE'29set -euo pipefail30DIR="$HOME/cluster-projects/ka2"31cd "$DIR"3233echo "--> venv + dépendances"34python3 -m venv .venv35./.venv/bin/python -m pip install -q --upgrade pip36./.venv/bin/python -m pip install -q -r requirements.txt3738PY="$DIR/.venv/bin/python"39UVICORN="$DIR/.venv/bin/uvicorn"40LOGS="$DIR/logs"; mkdir -p "$LOGS"41LA="$HOME/Library/LaunchAgents"; mkdir -p "$LA"4243write_plist () {44  local label="$1" ; shift45  local plist="$LA/${label}.plist"46  {47    echo '<?xml version="1.0" encoding="UTF-8"?>'48    echo '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'49    echo '<plist version="1.0"><dict>'50    echo "  <key>Label</key><string>${label}</string>"51    echo '  <key>ProgramArguments</key><array>'52    for a in "$@"; do echo "    <string>${a}</string>"; done53    echo '  </array>'54    echo "  <key>WorkingDirectory</key><string>${DIR}</string>"55    echo '  <key>RunAtLoad</key><true/>'56    echo '  <key>KeepAlive</key><true/>'57    echo "  <key>StandardOutPath</key><string>${LOGS}/${label}.out.log</string>"58    echo "  <key>StandardErrorPath</key><string>${LOGS}/${label}.err.log</string>"59    echo '  <key>EnvironmentVariables</key><dict>'60    echo "    <key>PATH</key><string>/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>"61    echo '  </dict>'62    echo '</dict></plist>'63  } > "$plist"64  launchctl unload "$plist" 2>/dev/null || true65  launchctl load "$plist"66  echo "    launchd chargé: ${label}"67}6869echo "--> services launchd"70write_plist "com.ka2.web"   "$UVICORN" "web.app:app" "--host" "127.0.0.1" "--port" "${PORT}"71write_plist "com.ka2.bot"   "$PY" "main.py" "run" "--daily-budget" "800" "--cycle-delay" "20"72write_plist "com.ka2.ngrok" "$NGROK" "http" "--url=https://${DOMAIN}" "${PORT}"7374echo "--> session : 15 min à partir de maintenant (bouton « Continuer » pour +15 min)"75"$PY" - <<'PYSET'76import time77from src.config import config78from src.storage import Store79s = Store(config.db_path)80s.set_setting("run_until", str(time.time() + 15 * 60))81s.set_setting("paused", "0")82s.close()83print("run_until = maintenant + 15 min")84PYSET8586sleep 587echo "--> healthcheck local"88curl -s "http://127.0.0.1:${PORT}/health" || echo "(web pas encore prêt)"89echo90echo "--> tunnel ngrok"91curl -s http://127.0.0.1:4040/api/tunnels 2>/dev/null | head -c 400 || echo "(api ngrok non prête)"92echo93REMOTE9495echo96echo "==> Déploiement terminé. Dashboard : https://${DOMAIN}"97