From a0c38a5cf307f4ae9c638770f67d13e2e314c954 Mon Sep 17 00:00:00 2001 From: Orion <1399928443@qq.com> Date: Wed, 11 Mar 2026 15:10:40 +0800 Subject: [PATCH] feat: add dev-daemon target for background development mode (#1047) * feat: add dev-daemon target for background development mode Add a new make dev-daemon target that allows running DeerFlow services in background mode without keeping the terminal connection. Following the pattern of PR #1042, the implementation uses a dedicated shell script (scripts/start-daemon.sh) for better maintainability. - Create scripts/start-daemon.sh for daemon mode startup - Add dev-daemon target to Makefile - Each service writes logs to separate files (langgraph, gateway, frontend, nginx) - Services can be stopped with make stop - Use nohup for proper daemon process detachment - Add cleanup on failure when services fail to start - Use more specific pkill pattern to avoid killing unrelated nginx processes * refactor: use wait-for-port.sh instead of hardcoded sleep in daemon script * refactor: use specific nginx process pattern to avoid killing unrelated processes * Revert "refactor: use specific nginx process pattern to avoid killing unrelated processes" This reverts commit 4c369155bfc91ccce347876a8982f955fa039da8. * refactor: use consistent nginx kill pattern across all scripts * chore(daemon): add trap for cleanup on interrupt signals * fix(daemon): pass repo root as positional argument to nginx command --------- Co-authored-by: Willem Jiang --- Makefile | 7 ++- scripts/start-daemon.sh | 129 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+), 1 deletion(-) create mode 100755 scripts/start-daemon.sh diff --git a/Makefile b/Makefile index fec6120..ab0fd69 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # DeerFlow - Unified Development Environment -.PHONY: help config check install dev start stop clean docker-init docker-start docker-stop docker-logs docker-logs-frontend docker-logs-gateway +.PHONY: help config check install dev dev-daemon start stop clean docker-init docker-start docker-stop docker-logs docker-logs-frontend docker-logs-gateway help: @echo "DeerFlow Development Commands:" @@ -9,6 +9,7 @@ help: @echo " make install - Install all dependencies (frontend + backend)" @echo " make setup-sandbox - Pre-pull sandbox container image (recommended)" @echo " make dev - Start all services in development mode (with hot-reloading)" + @echo " make dev-daemon - Start all services in background (daemon mode)" @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" @@ -87,6 +88,10 @@ dev: start: @./scripts/serve.sh --prod +# Start all services in daemon mode (background) +dev-daemon: + @./scripts/start-daemon.sh + # Stop all services stop: @echo "Stopping all services..." diff --git a/scripts/start-daemon.sh b/scripts/start-daemon.sh new file mode 100755 index 0000000..16350c9 --- /dev/null +++ b/scripts/start-daemon.sh @@ -0,0 +1,129 @@ +#!/usr/bin/env bash +# +# start-daemon.sh - Start all DeerFlow development services in daemon mode +# +# This script starts DeerFlow services in the background without keeping +# the terminal connection. Logs are written to separate files. +# +# Must be run from the repo root directory. + +set -e + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$REPO_ROOT" + +# ── 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 +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 +./scripts/cleanup-containers.sh deer-flow-sandbox 2>/dev/null || true +sleep 1 + +# ── Banner ──────────────────────────────────────────────────────────────────── + +echo "" +echo "==========================================" +echo " Starting DeerFlow in Daemon Mode" +echo "==========================================" +echo "" + +# ── Config check ───────────────────────────────────────────────────────────── + +if ! { \ + [ -n "$DEER_FLOW_CONFIG_PATH" ] && [ -f "$DEER_FLOW_CONFIG_PATH" ] || \ + [ -f backend/config.yaml ] || \ + [ -f config.yaml ]; \ + }; then + echo "✗ No DeerFlow config file found." + echo " Checked these locations:" + echo " - $DEER_FLOW_CONFIG_PATH (when DEER_FLOW_CONFIG_PATH is set)" + echo " - backend/config.yaml" + echo " - ./config.yaml" + echo "" + echo " Run 'make config' from the repo root to generate ./config.yaml, then set required model API keys in .env or your config file." + exit 1 +fi + +# ── Cleanup on failure ─────────────────────────────────────────────────────── + +cleanup_on_failure() { + echo "Failed to start services, cleaning up..." + 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 + 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 + echo "✓ Cleanup complete" +} + +trap cleanup_on_failure INT TERM + +# ── Start services ──────────────────────────────────────────────────────────── + +mkdir -p logs + +echo "Starting LangGraph server..." +nohup sh -c 'cd backend && NO_COLOR=1 uv run langgraph dev --no-browser --allow-blocking --no-reload > ../logs/langgraph.log 2>&1' & +./scripts/wait-for-port.sh 2024 60 "LangGraph" || { + echo "✗ LangGraph failed to start. Last log output:" + tail -60 logs/langgraph.log + cleanup_on_failure + exit 1 +} +echo "✓ LangGraph server started on localhost:2024" + +echo "Starting Gateway API..." +nohup sh -c 'cd backend && uv run uvicorn src.gateway.app:app --host 0.0.0.0 --port 8001 > ../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 + cleanup_on_failure + exit 1 +} +echo "✓ Gateway API started on localhost:8001" + +echo "Starting Frontend..." +nohup sh -c 'cd frontend && pnpm run dev > ../logs/frontend.log 2>&1' & +./scripts/wait-for-port.sh 3000 120 "Frontend" || { + echo "✗ Frontend failed to start. Last log output:" + tail -60 logs/frontend.log + cleanup_on_failure + exit 1 +} +echo "✓ Frontend started on localhost:3000" + +echo "Starting Nginx reverse proxy..." +nohup sh -c 'nginx -g "daemon off;" -c "$1/docker/nginx/nginx.local.conf" -p "$1" > logs/nginx.log 2>&1' _ "$REPO_ROOT" & +./scripts/wait-for-port.sh 2026 10 "Nginx" || { + echo "✗ Nginx failed to start. Last log output:" + tail -60 logs/nginx.log + cleanup_on_failure + exit 1 +} +echo "✓ Nginx started on localhost:2026" + +# ── Ready ───────────────────────────────────────────────────────────────────── + +echo "" +echo "==========================================" +echo " DeerFlow is running in daemon mode!" +echo "==========================================" +echo "" +echo " 🌐 Application: http://localhost:2026" +echo " 📡 API Gateway: http://localhost:2026/api/*" +echo " 🤖 LangGraph: http://localhost:2026/api/langgraph/*" +echo "" +echo " 📋 Logs:" +echo " - LangGraph: logs/langgraph.log" +echo " - Gateway: logs/gateway.log" +echo " - Frontend: logs/frontend.log" +echo " - Nginx: logs/nginx.log" +echo "" +echo " 🛑 Stop daemon: make stop" +echo ""