Add dev.sh for running server + client in parallel on macOS, and prod.sh for building and deploying in production. The Rust server now serves static client files with SPA fallback, eliminating the need for Vite in production. Also adds missing BRAVE_API_KEY to .env.example. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
151 lines
4.7 KiB
Bash
Executable File
151 lines
4.7 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
|
|
|
|
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 [ -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
|
|
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
|