diff --git a/Makefile b/Makefile index 3f2079a..fec6120 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # DeerFlow - Unified Development Environment -.PHONY: help config check install dev stop clean docker-init docker-start docker-stop docker-logs docker-logs-frontend docker-logs-gateway +.PHONY: help config check install dev start stop clean docker-init docker-start docker-stop docker-logs docker-logs-frontend docker-logs-gateway help: @echo "DeerFlow Development Commands:" @@ -8,7 +8,8 @@ help: @echo " make check - Check if all required tools are installed" @echo " make install - Install all dependencies (frontend + backend)" @echo " make setup-sandbox - Pre-pull sandbox container image (recommended)" - @echo " make dev - Start all services (frontend + backend + nginx on localhost:2026)" + @echo " make dev - Start all services in development mode (with hot-reloading)" + @echo " make start - Start all services in production mode (optimized, no hot-reloading)" @echo " make stop - Stop all running services" @echo " make clean - Clean up processes and temporary files" @echo "" @@ -31,78 +32,7 @@ config: # Check required tools check: - @echo "==========================================" - @echo " Checking Required Dependencies" - @echo "==========================================" - @echo "" - @FAILED=0; \ - echo "Checking Node.js..."; \ - if command -v node >/dev/null 2>&1; then \ - NODE_VERSION=$$(node -v | sed 's/v//'); \ - NODE_MAJOR=$$(echo $$NODE_VERSION | cut -d. -f1); \ - if [ $$NODE_MAJOR -ge 22 ]; then \ - echo " ✓ Node.js $$NODE_VERSION (>= 22 required)"; \ - else \ - echo " ✗ Node.js $$NODE_VERSION found, but version 22+ is required"; \ - echo " Install from: https://nodejs.org/"; \ - FAILED=1; \ - fi; \ - else \ - echo " ✗ Node.js not found (version 22+ required)"; \ - echo " Install from: https://nodejs.org/"; \ - FAILED=1; \ - fi; \ - echo ""; \ - echo "Checking pnpm..."; \ - if command -v pnpm >/dev/null 2>&1; then \ - PNPM_VERSION=$$(pnpm -v); \ - echo " ✓ pnpm $$PNPM_VERSION"; \ - else \ - echo " ✗ pnpm not found"; \ - echo " Install: npm install -g pnpm"; \ - echo " Or visit: https://pnpm.io/installation"; \ - FAILED=1; \ - fi; \ - echo ""; \ - echo "Checking uv..."; \ - if command -v uv >/dev/null 2>&1; then \ - UV_VERSION=$$(uv --version | awk '{print $$2}'); \ - echo " ✓ uv $$UV_VERSION"; \ - else \ - echo " ✗ uv not found"; \ - echo " Install: curl -LsSf https://astral.sh/uv/install.sh | sh"; \ - echo " Or visit: https://docs.astral.sh/uv/getting-started/installation/"; \ - FAILED=1; \ - fi; \ - echo ""; \ - echo "Checking nginx..."; \ - if command -v nginx >/dev/null 2>&1; then \ - NGINX_VERSION=$$(nginx -v 2>&1 | awk -F'/' '{print $$2}'); \ - echo " ✓ nginx $$NGINX_VERSION"; \ - else \ - echo " ✗ nginx not found"; \ - echo " macOS: brew install nginx"; \ - echo " Ubuntu: sudo apt install nginx"; \ - echo " Or visit: https://nginx.org/en/download.html"; \ - FAILED=1; \ - fi; \ - echo ""; \ - if [ $$FAILED -eq 0 ]; then \ - echo "=========================================="; \ - echo " ✓ All dependencies are installed!"; \ - echo "=========================================="; \ - echo ""; \ - echo "You can now run:"; \ - echo " make install - Install project dependencies"; \ - echo " make dev - Start development server"; \ - else \ - echo "=========================================="; \ - echo " ✗ Some dependencies are missing"; \ - echo "=========================================="; \ - echo ""; \ - echo "Please install the missing tools and run 'make check' again."; \ - exit 1; \ - fi + @./scripts/check.sh # Install all dependencies install: @@ -149,9 +79,13 @@ setup-sandbox: exit 1; \ fi -# Start all services +# Start all services in development mode (with hot-reloading) dev: - @./scripts/start.sh + @./scripts/serve.sh --dev + +# Start all services in production mode (with optimizations) +start: + @./scripts/serve.sh --prod # Stop all services stop: @@ -159,6 +93,9 @@ stop: @-pkill -f "langgraph dev" 2>/dev/null || true @-pkill -f "uvicorn src.gateway.app:app" 2>/dev/null || true @-pkill -f "next dev" 2>/dev/null || true + @-pkill -f "next start" 2>/dev/null || true + @-pkill -f "next-server" 2>/dev/null || true + @-pkill -f "next-server" 2>/dev/null || true @-nginx -c $(PWD)/docker/nginx/nginx.local.conf -p $(PWD) -s quit 2>/dev/null || true @sleep 1 @-pkill -9 nginx 2>/dev/null || true @@ -169,6 +106,8 @@ stop: # Clean up clean: stop @echo "Cleaning up..." + @-rm -rf backend/.deer-flow 2>/dev/null || true + @-rm -rf backend/.langgraph_api 2>/dev/null || true @-rm -rf logs/*.log 2>/dev/null || true @echo "✓ Cleanup complete" diff --git a/scripts/check.sh b/scripts/check.sh new file mode 100755 index 0000000..43863ae --- /dev/null +++ b/scripts/check.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash +set -euo pipefail + +echo "==========================================" +echo " Checking Required Dependencies" +echo "==========================================" +echo "" + +FAILED=0 + +echo "Checking Node.js..." +if command -v node >/dev/null 2>&1; then + NODE_VERSION=$(node -v | sed 's/v//') + NODE_MAJOR=$(echo "$NODE_VERSION" | cut -d. -f1) + if [ "$NODE_MAJOR" -ge 22 ]; then + echo " ✓ Node.js $NODE_VERSION (>= 22 required)" + else + echo " ✗ Node.js $NODE_VERSION found, but version 22+ is required" + echo " Install from: https://nodejs.org/" + FAILED=1 + fi +else + echo " ✗ Node.js not found (version 22+ required)" + echo " Install from: https://nodejs.org/" + FAILED=1 +fi + +echo "" +echo "Checking pnpm..." +if command -v pnpm >/dev/null 2>&1; then + PNPM_VERSION=$(pnpm -v) + echo " ✓ pnpm $PNPM_VERSION" +else + echo " ✗ pnpm not found" + echo " Install: npm install -g pnpm" + echo " Or visit: https://pnpm.io/installation" + FAILED=1 +fi + +echo "" +echo "Checking uv..." +if command -v uv >/dev/null 2>&1; then + UV_VERSION=$(uv --version | awk '{print $2}') + echo " ✓ uv $UV_VERSION" +else + echo " ✗ uv not found" + echo " Install: curl -LsSf https://astral.sh/uv/install.sh | sh" + echo " Or visit: https://docs.astral.sh/uv/getting-started/installation/" + FAILED=1 +fi + +echo "" +echo "Checking nginx..." +if command -v nginx >/dev/null 2>&1; then + NGINX_VERSION=$(nginx -v 2>&1 | awk -F'/' '{print $2}') + echo " ✓ nginx $NGINX_VERSION" +else + echo " ✗ nginx not found" + echo " macOS: brew install nginx" + echo " Ubuntu: sudo apt install nginx" + echo " Or visit: https://nginx.org/en/download.html" + FAILED=1 +fi + +echo "" +if [ "$FAILED" -eq 0 ]; then + echo "==========================================" + echo " ✓ All dependencies are installed!" + echo "==========================================" + echo "" + echo "You can now run:" + echo " make install - Install project dependencies" + echo " make config - Generate local config files" + echo " make dev - Start development server" + echo " make start - Start production server" +else + echo "==========================================" + echo " ✗ Some dependencies are missing" + echo "==========================================" + echo "" + echo "Please install the missing tools and run 'make check' again." + exit 1 +fi diff --git a/scripts/start.sh b/scripts/serve.sh similarity index 78% rename from scripts/start.sh rename to scripts/serve.sh index 3022db0..72d1afb 100755 --- a/scripts/start.sh +++ b/scripts/serve.sh @@ -9,12 +9,30 @@ set -e REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$REPO_ROOT" +# ── Argument parsing ───────────────────────────────────────────────────────── + +DEV_MODE=true +for arg in "$@"; do + case "$arg" in + --dev) DEV_MODE=true ;; + --prod) DEV_MODE=false ;; + *) echo "Unknown argument: $arg"; echo "Usage: $0 [--dev|--prod]"; exit 1 ;; + esac +done + +if $DEV_MODE; then + FRONTEND_CMD="pnpm run dev" +else + FRONTEND_CMD="env BETTER_AUTH_SECRET=$(python3 -c 'import secrets; print(secrets.token_hex(16))') pnpm run preview" +fi + # ── Stop existing services ──────────────────────────────────────────────────── echo "Stopping existing services if any..." pkill -f "langgraph dev" 2>/dev/null || true pkill -f "uvicorn src.gateway.app:app" 2>/dev/null || true pkill -f "next dev" 2>/dev/null || true +pkill -f "next-server" 2>/dev/null || true nginx -c "$REPO_ROOT/docker/nginx/nginx.local.conf" -p "$REPO_ROOT" -s quit 2>/dev/null || true sleep 1 pkill -9 nginx 2>/dev/null || true @@ -29,6 +47,14 @@ echo "==========================================" echo " Starting DeerFlow Development Server" echo "==========================================" echo "" +if $DEV_MODE; then + echo " Mode: DEV (hot-reload enabled)" + echo " Tip: run \`make start\` in production mode" +else + echo " Mode: PROD (hot-reload disabled)" + echo " Tip: run \`make dev\` to start in development mode" +fi +echo "" echo "Services starting up..." echo " → Backend: LangGraph + Gateway" echo " → Frontend: Next.js" @@ -61,6 +87,7 @@ cleanup() { pkill -f "langgraph dev" 2>/dev/null || true pkill -f "uvicorn src.gateway.app:app" 2>/dev/null || true pkill -f "next dev" 2>/dev/null || true + pkill -f "next start" 2>/dev/null || true # Kill nginx using the captured PID first (most reliable), # then fall back to pkill/killall for any stray nginx workers. if [ -n "${NGINX_PID:-}" ] && kill -0 "$NGINX_PID" 2>/dev/null; then @@ -81,8 +108,16 @@ trap cleanup INT TERM mkdir -p logs +if $DEV_MODE; then + LANGGRAPH_EXTRA_FLAGS="" + GATEWAY_EXTRA_FLAGS="--reload --reload-include='*.yaml' --reload-include='.env'" +else + LANGGRAPH_EXTRA_FLAGS="--no-reload" + GATEWAY_EXTRA_FLAGS="" +fi + echo "Starting LangGraph server..." -(cd backend && NO_COLOR=1 uv run langgraph dev --no-browser --allow-blocking --no-reload > ../logs/langgraph.log 2>&1) & +(cd backend && NO_COLOR=1 uv run langgraph dev --no-browser --allow-blocking $LANGGRAPH_EXTRA_FLAGS > ../logs/langgraph.log 2>&1) & ./scripts/wait-for-port.sh 2024 60 "LangGraph" || { echo " See logs/langgraph.log for details" tail -20 logs/langgraph.log @@ -91,7 +126,7 @@ echo "Starting LangGraph server..." echo "✓ LangGraph server started on localhost:2024" echo "Starting Gateway API..." -(cd backend && uv run uvicorn src.gateway.app:app --host 0.0.0.0 --port 8001 > ../logs/gateway.log 2>&1) & +(cd backend && uv run uvicorn src.gateway.app:app --host 0.0.0.0 --port 8001 $GATEWAY_EXTRA_FLAGS > ../logs/gateway.log 2>&1) & ./scripts/wait-for-port.sh 8001 30 "Gateway API" || { echo "✗ Gateway API failed to start. Last log output:" tail -60 logs/gateway.log @@ -103,7 +138,7 @@ echo "Starting Gateway API..." echo "✓ Gateway API started on localhost:8001" echo "Starting Frontend..." -(cd frontend && pnpm run dev > ../logs/frontend.log 2>&1) & +(cd frontend && $FRONTEND_CMD > ../logs/frontend.log 2>&1) & ./scripts/wait-for-port.sh 3000 120 "Frontend" || { echo " See logs/frontend.log for details" tail -20 logs/frontend.log @@ -125,7 +160,11 @@ echo "✓ Nginx started on localhost:2026" echo "" echo "==========================================" -echo " DeerFlow is ready!" +if $DEV_MODE; then + echo " ✓ DeerFlow development server is running!" +else + echo " ✓ DeerFlow production server is running!" +fi echo "==========================================" echo "" echo " 🌐 Application: http://localhost:2026" @@ -139,6 +178,5 @@ echo " - Frontend: logs/frontend.log" echo " - Nginx: logs/nginx.log" echo "" echo "Press Ctrl+C to stop all services" -echo "" wait