groupchat/prod.sh
Jason Tudisco 927d106eae Add provider-based web search with Tavily support
- Add `SEARCH_PROVIDER` config with Tavily/Brave API key validation in server and prod script
- Introduce unified `web_search` tool and shared search service with Tavily + Brave backends
- Update chat UI tool status/result labels to treat both search tools consistently
2026-03-16 20:18:27 -06:00

163 lines
5.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# GroupChat2 Production Build & Run Script
# Builds the client, compiles the server in release mode, and runs it.
# The Rust server serves the static client files directly — no Vite needed.
#
# Usage:
# ./prod.sh # Build + run
# ./prod.sh build # Build only (no run)
# ./prod.sh run # Run only (skip build, assumes already built)
set -e
ROOT="$(cd "$(dirname "$0")" && pwd)"
# Colors
MAGENTA='\033[0;35m'
YELLOW='\033[0;33m'
CYAN='\033[0;36m'
RED='\033[0;31m'
GREEN='\033[0;32m'
GRAY='\033[0;90m'
NC='\033[0m'
MODE="${1:-all}" # all | build | run
# ─── Preflight checks ───────────────────────────────────────────────
check_env() {
if [ ! -f "$ROOT/server/.env" ]; then
echo -e "${RED}[prod] Missing server/.env file!${NC}"
echo -e "${GRAY} Copy server/.env.example and fill in your keys:${NC}"
echo -e "${GRAY} cp server/.env.example server/.env${NC}"
exit 1
fi
# Source .env to validate required vars
set -a
source "$ROOT/server/.env"
set +a
SEARCH_PROVIDER="${SEARCH_PROVIDER:-tavily}"
if [ -z "$OPENROUTER_API_KEY" ] || [ "$OPENROUTER_API_KEY" = "your-openrouter-api-key-here" ]; then
echo -e "${RED}[prod] OPENROUTER_API_KEY not set in server/.env${NC}"
exit 1
fi
if [ "$SEARCH_PROVIDER" = "tavily" ]; then
if [ -z "$TAVILY_API_KEY" ] || [ "$TAVILY_API_KEY" = "tvly-your-key-here" ]; then
echo -e "${RED}[prod] TAVILY_API_KEY not set in server/.env${NC}"
exit 1
fi
elif [ "$SEARCH_PROVIDER" = "brave" ]; then
if [ -z "$BRAVE_API_KEY" ] || [ "$BRAVE_API_KEY" = "your-brave-api-key-here" ]; then
echo -e "${RED}[prod] BRAVE_API_KEY not set in server/.env${NC}"
exit 1
fi
else
echo -e "${RED}[prod] SEARCH_PROVIDER must be 'tavily' or 'brave'${NC}"
exit 1
fi
if [ -z "$JWT_SECRET" ] || [ "$JWT_SECRET" = "dev-secret-change-me" ]; then
echo -e "${YELLOW}[prod] WARNING: Using default JWT_SECRET — set a real secret for production!${NC}"
fi
}
# ─── Build ───────────────────────────────────────────────────────────
build() {
echo -e "${MAGENTA}[prod] Building GroupChat2 for production...${NC}"
echo ""
# 1. Install client deps if needed
if [ ! -d "$ROOT/client/node_modules" ]; then
echo -e "${CYAN}[prod] Installing client dependencies...${NC}"
(cd "$ROOT/client" && npm install)
fi
# 2. Build client (Vite → dist/)
echo -e "${CYAN}[prod] Building client...${NC}"
(cd "$ROOT/client" && npm run build)
echo -e "${GREEN}[prod] Client built → client/dist/${NC}"
# 3. Build server in release mode
echo -e "${YELLOW}[prod] Building server (release)...${NC}"
(cd "$ROOT/server" && cargo build --release)
echo -e "${GREEN}[prod] Server built → server/target/release/groupchat-server${NC}"
echo ""
echo -e "${GREEN}[prod] Build complete!${NC}"
}
# ─── Run ─────────────────────────────────────────────────────────────
run() {
check_env
# Verify build artifacts exist
if [ ! -f "$ROOT/server/target/release/groupchat-server" ]; then
echo -e "${RED}[prod] Server binary not found. Run './prod.sh build' first.${NC}"
exit 1
fi
if [ ! -d "$ROOT/client/dist" ]; then
echo -e "${RED}[prod] Client dist not found. Run './prod.sh build' first.${NC}"
exit 1
fi
BIND_ADDR="${BIND_ADDR:-0.0.0.0:3001}"
echo ""
echo -e " ${MAGENTA}GroupChat2 Production${NC}"
echo -e " ${GREEN}Domain: https://gchat.tud.ink${NC}"
echo -e " ${YELLOW}Bind: ${BIND_ADDR}${NC}"
echo -e " ${GRAY}Press Ctrl+C to stop${NC}"
echo ""
# Source .env so the server binary picks up the vars
set -a
source "$ROOT/server/.env"
set +a
export STATIC_DIR="$ROOT/client/dist"
export BIND_ADDR
export RUST_LOG="${RUST_LOG:-info}"
cleanup() {
echo ""
echo -e "${RED}[prod] Shutting down...${NC}"
kill "$SERVER_PID" 2>/dev/null || true
lsof -ti:3001 2>/dev/null | xargs kill -9 2>/dev/null || true
echo -e "${RED}[prod] Stopped.${NC}"
exit 0
}
trap cleanup INT TERM
# Run the release binary
"$ROOT/server/target/release/groupchat-server" &
SERVER_PID=$!
wait "$SERVER_PID"
}
# ─── Main ────────────────────────────────────────────────────────────
case "$MODE" in
build)
build
;;
run)
run
;;
all|"")
build
run
;;
*)
echo "Usage: $0 [build|run]"
echo " (no args) Build and run"
echo " build Build only"
echo " run Run only (must build first)"
exit 1
;;
esac