From 59e20adb658718b3ddecb105e411e7d7b39ab24b Mon Sep 17 00:00:00 2001 From: Zak Stam Date: Tue, 19 Aug 2025 13:11:51 +0300 Subject: [PATCH 01/15] Add improved development environment with backend in Docker and frontend locally - Created dev.bat script to run backend services in Docker and frontend locally - Added docker-compose.backend.yml for backend-only Docker setup - Updated package.json to run frontend on port 3737 - Fixed api.ts to use default port 8181 instead of throwing error - Script automatically stops production containers to avoid port conflicts - Provides instant HMR for frontend development --- archon-ui-main/package.json | 2 +- archon-ui-main/src/config/api.ts | 11 +--- dev.bat | 90 +++++++++++++++++++++++++ docker-compose.backend.yml | 109 +++++++++++++++++++++++++++++++ 4 files changed, 202 insertions(+), 10 deletions(-) create mode 100644 dev.bat create mode 100644 docker-compose.backend.yml diff --git a/archon-ui-main/package.json b/archon-ui-main/package.json index fc6a1d1a60..4e88d678be 100644 --- a/archon-ui-main/package.json +++ b/archon-ui-main/package.json @@ -4,7 +4,7 @@ "private": true, "type": "module", "scripts": { - "dev": "npx vite", + "dev": "npx vite --port 3737 --host", "build": "npx vite build", "lint": "eslint . --ext .js,.jsx,.ts,.tsx", "preview": "npx vite preview", diff --git a/archon-ui-main/src/config/api.ts b/archon-ui-main/src/config/api.ts index 6b7799b380..437e1126f5 100644 --- a/archon-ui-main/src/config/api.ts +++ b/archon-ui-main/src/config/api.ts @@ -20,15 +20,8 @@ export function getApiUrl(): string { // For development, construct from window location const protocol = window.location.protocol; const host = window.location.hostname; - const port = import.meta.env.ARCHON_SERVER_PORT; - - if (!port) { - throw new Error( - 'ARCHON_SERVER_PORT environment variable is required. ' + - 'Please set it in your environment variables. ' + - 'Default value: 8181' - ); - } + // Try VITE_ prefixed env var first, then fallback to default + const port = import.meta.env.VITE_ARCHON_SERVER_PORT || '8181'; return `${protocol}//${host}:${port}`; } diff --git a/dev.bat b/dev.bat new file mode 100644 index 0000000000..290e63c584 --- /dev/null +++ b/dev.bat @@ -0,0 +1,90 @@ +@echo off +REM Development environment - Python in Docker, Frontend locally + +echo Starting Archon development environment... +echo Python services in Docker, Frontend running locally + +REM Check if .env file exists +if not exist .env goto no_env_file + +REM Set Docker BuildKit for faster builds +set DOCKER_BUILDKIT=1 +set COMPOSE_DOCKER_CLI_BUILD=1 + +REM Check if production/deployment containers are running and stop them +echo Checking for running production containers... +docker ps | findstr "Archon-Server Archon-UI Archon-MCP Archon-Agents" >nul 2>&1 +if %errorlevel%==0 ( + echo Production containers detected. Stopping them to avoid port conflicts... + docker-compose down + echo Production containers stopped. + echo. +) + +REM Check if backend containers are already running +docker ps | findstr "Archon-Backend-Server" >nul 2>&1 +if %errorlevel%==0 goto containers_running + +REM Check if backend containers exist but are stopped +docker ps -a | findstr "Archon-Backend-Server" >nul 2>&1 +if %errorlevel%==0 goto start_existing + +:build_new +echo Building backend containers for first time... +docker-compose -p archon-backend -f docker-compose.backend.yml up -d --build +goto wait_for_services + +:start_existing +echo Starting existing backend containers... +docker-compose -p archon-backend -f docker-compose.backend.yml start +goto wait_for_services + +:containers_running +echo Backend containers already running. No rebuild needed. + +:wait_for_services +REM Wait for backend services to be ready +echo Waiting for backend services... +timeout /t 3 /nobreak > nul + +REM Check backend health +docker-compose -p archon-backend -f docker-compose.backend.yml ps + +echo. +echo Backend services started in Docker! +echo. +echo Starting frontend locally... +echo. + +REM Start frontend locally in a new window +cd archon-ui-main +start "Archon Frontend" cmd /k "npm run dev" +cd .. + +echo. +echo =================================================== +echo Development Environment Ready! +echo =================================================== +echo. +echo Backend Services in Docker: +echo API Server: http://localhost:8181 +echo MCP Server: http://localhost:8051 +echo Agents Service: http://localhost:8052 +echo. +echo Frontend running locally: +echo UI with HMR: http://localhost:3737 +echo. +echo Commands: +echo Backend logs: docker-compose -p archon-backend -f docker-compose.backend.yml logs -f +echo Stop backend: docker-compose -p archon-backend -f docker-compose.backend.yml stop +echo Remove backend: docker-compose -p archon-backend -f docker-compose.backend.yml down +echo. +echo Frontend is running in a separate window with full HMR support! +echo Edit files in archon-ui-main/ and see instant updates. +goto end + +:no_env_file +echo ERROR: .env file not found. Please copy .env.example to .env and configure it. +exit /b 1 + +:end \ No newline at end of file diff --git a/docker-compose.backend.yml b/docker-compose.backend.yml new file mode 100644 index 0000000000..460b5890ac --- /dev/null +++ b/docker-compose.backend.yml @@ -0,0 +1,109 @@ +# Backend-only services for hybrid development +# Python services run in Docker, frontend runs locally + +services: + # Backend Server Service (FastAPI + Socket.IO) + backend-server: + build: + context: ./python + dockerfile: Dockerfile.server + args: + BUILDKIT_INLINE_CACHE: 1 + ARCHON_SERVER_PORT: ${ARCHON_SERVER_PORT:-8181} + container_name: Archon-Backend-Server + ports: + - "${ARCHON_SERVER_PORT:-8181}:${ARCHON_SERVER_PORT:-8181}" + environment: + - SUPABASE_URL=${SUPABASE_URL} + - SUPABASE_SERVICE_KEY=${SUPABASE_SERVICE_KEY} + - OPENAI_API_KEY=${OPENAI_API_KEY:-} + - LOGFIRE_TOKEN=${LOGFIRE_TOKEN:-} + - SERVICE_DISCOVERY_MODE=docker_compose + - LOG_LEVEL=${LOG_LEVEL:-DEBUG} + - ARCHON_SERVER_PORT=${ARCHON_SERVER_PORT:-8181} + - ARCHON_MCP_PORT=${ARCHON_MCP_PORT:-8051} + - ARCHON_AGENTS_PORT=${ARCHON_AGENTS_PORT:-8052} + - PYTHONUNBUFFERED=1 + - PYTHONDONTWRITEBYTECODE=1 + networks: + - backend-network + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./python/src:/app/src # Hot reload for Python + - ./python/tests:/app/tests + command: ["python", "-m", "uvicorn", "src.server.main:socket_app", "--host", "0.0.0.0", "--port", "${ARCHON_SERVER_PORT:-8181}", "--reload"] + healthcheck: + test: ["CMD", "sh", "-c", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:${ARCHON_SERVER_PORT:-8181}/health')\""] + interval: 10s + timeout: 5s + retries: 3 + start_period: 20s + + # MCP Server Service + backend-mcp: + build: + context: ./python + dockerfile: Dockerfile.mcp + args: + BUILDKIT_INLINE_CACHE: 1 + ARCHON_MCP_PORT: ${ARCHON_MCP_PORT:-8051} + container_name: Archon-Backend-MCP + ports: + - "${ARCHON_MCP_PORT:-8051}:${ARCHON_MCP_PORT:-8051}" + environment: + - SUPABASE_URL=${SUPABASE_URL} + - SUPABASE_SERVICE_KEY=${SUPABASE_SERVICE_KEY} + - LOGFIRE_TOKEN=${LOGFIRE_TOKEN:-} + - SERVICE_DISCOVERY_MODE=docker_compose + - TRANSPORT=sse + - LOG_LEVEL=${LOG_LEVEL:-DEBUG} + - API_SERVICE_URL=http://backend-server:${ARCHON_SERVER_PORT:-8181} + - AGENTS_SERVICE_URL=http://backend-agents:${ARCHON_AGENTS_PORT:-8052} + - ARCHON_MCP_PORT=${ARCHON_MCP_PORT:-8051} + - ARCHON_SERVER_PORT=${ARCHON_SERVER_PORT:-8181} + - ARCHON_AGENTS_PORT=${ARCHON_AGENTS_PORT:-8052} + networks: + - backend-network + depends_on: + - backend-server + - backend-agents + healthcheck: + test: ["CMD", "sh", "-c", "python -c \"import socket; s=socket.socket(); s.connect(('localhost', ${ARCHON_MCP_PORT:-8051})); s.close()\""] + interval: 10s + timeout: 5s + retries: 3 + start_period: 30s + + # Agents Service + backend-agents: + build: + context: ./python + dockerfile: Dockerfile.agents + args: + BUILDKIT_INLINE_CACHE: 1 + ARCHON_AGENTS_PORT: ${ARCHON_AGENTS_PORT:-8052} + container_name: Archon-Backend-Agents + ports: + - "${ARCHON_AGENTS_PORT:-8052}:${ARCHON_AGENTS_PORT:-8052}" + environment: + - SUPABASE_URL=${SUPABASE_URL} + - SUPABASE_SERVICE_KEY=${SUPABASE_SERVICE_KEY} + - OPENAI_API_KEY=${OPENAI_API_KEY:-} + - LOGFIRE_TOKEN=${LOGFIRE_TOKEN:-} + - SERVICE_DISCOVERY_MODE=docker_compose + - LOG_LEVEL=${LOG_LEVEL:-DEBUG} + - ARCHON_AGENTS_PORT=${ARCHON_AGENTS_PORT:-8052} + - PYTHONUNBUFFERED=1 + - PYTHONDONTWRITEBYTECODE=1 + networks: + - backend-network + healthcheck: + test: ["CMD", "sh", "-c", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:${ARCHON_AGENTS_PORT:-8052}/health')\""] + interval: 10s + timeout: 5s + retries: 3 + start_period: 20s + +networks: + backend-network: + driver: bridge \ No newline at end of file From 85957c13637fce59952a82d2e85507c61c494a85 Mon Sep 17 00:00:00 2001 From: Zak Stam Date: Thu, 21 Aug 2025 18:21:47 +0300 Subject: [PATCH 02/15] Refactor development environment setup: replace dev.bat with Makefile for cross-platform support and enhanced commands --- Makefile | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 156 ++++++++++++++++++++++++++++++-- dev.bat | 90 ------------------- 3 files changed, 408 insertions(+), 99 deletions(-) create mode 100644 Makefile delete mode 100644 dev.bat diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..5e6776a08c --- /dev/null +++ b/Makefile @@ -0,0 +1,261 @@ +# Archon Development Makefile +# Cross-platform development environment management + +.PHONY: help dev dev-hybrid dev-docker prod build test clean clean-confirm deep-clean deep-clean-confirm stop logs status install check-env + +# Default target - show help +help: + @echo "Archon Development Environment" + @echo "==============================" + @echo "" + @echo "Quick Start:" + @echo " make install - Install all dependencies" + @echo " make dev - Start hybrid dev environment (backend in Docker, frontend local)" + @echo " make prod - Start production environment (all in Docker)" + @echo "" + @echo "Development Modes:" + @echo " make dev-hybrid - Backend in Docker, frontend locally with HMR (default)" + @echo " make dev-docker - Everything in Docker (slower frontend updates)" + @echo "" + @echo "Management:" + @echo " make stop - Stop all running containers" + @echo " make clean - Stop and remove all containers and volumes" + @echo " make logs - Show logs from all services" + @echo " make status - Show status of all services" + @echo "" + @echo "Testing:" + @echo " make test - Run all tests (frontend and backend)" + @echo " make test-frontend - Run frontend tests only" + @echo " make test-backend - Run backend tests only" + @echo "" + @echo "Individual Services:" + @echo " make frontend - Start frontend only (local)" + @echo " make backend - Start backend services only (Docker)" + @echo "" + +# Install all dependencies +install: + @echo "Installing dependencies..." + @cd archon-ui-main && npm install + @cd python && uv sync + @echo "Dependencies installed successfully!" + +# Check and install frontend dependencies if needed +check-frontend-deps: + @cd archon-ui-main && npm install --silent + +# Default dev target - hybrid mode +dev: dev-hybrid + +# Hybrid development - backend in Docker, frontend local +dev-hybrid: stop-prod check-frontend-deps + @echo "Starting hybrid development environment..." + @echo "Backend services in Docker, Frontend running locally" + @docker-compose -p archon-backend -f docker-compose.backend.yml up -d --build + @echo "" + @echo "=====================================================" + @echo "Development Environment Ready!" + @echo "=====================================================" + @echo "" + @echo "Backend Services in Docker:" + @echo " API Server: http://localhost:8181" + @echo " MCP Server: http://localhost:8051" + @echo " Agents Service: http://localhost:8052" + @echo "" + @echo "Starting frontend server..." + @echo "" + @echo "Commands (in another terminal):" + @echo " make logs - View all logs" + @echo " make stop - Stop everything" + @echo " make status - Check service status" + @echo "" + @cd archon-ui-main && npm run dev + +# Full Docker development +dev-docker: + @echo "Starting full Docker development environment..." + docker-compose up -d --build + @echo "All services running in Docker" + @echo "UI available at: http://localhost:3737" + +# Production environment +prod: + @echo "Starting production environment..." + docker-compose up -d --build + @echo "Production environment started" + @echo "UI available at: http://localhost:3737" + +# Start backend services only +backend: + @echo "Starting backend services in Docker..." + docker-compose -p archon-backend -f docker-compose.backend.yml up -d --build + +# Start frontend only (foreground) +frontend: + @cd archon-ui-main && npm run dev + +# Stop production containers if running +stop-prod: + @echo "Checking for running production containers..." + -@docker-compose down + -@docker-compose -p archon-backend -f docker-compose.backend.yml down + @echo "Containers stopped" + +# Build all Docker images +build: + @echo "Building all Docker images..." + docker-compose build + docker-compose -f docker-compose.backend.yml build + +# Run all tests +test: test-frontend test-backend + +# Run frontend tests +test-frontend: + @echo "Running frontend tests..." + @cd archon-ui-main && npm run test + +# Run backend tests +test-backend: + @echo "Running backend tests..." + @cd python && uv run pytest + +# Run frontend tests with coverage +test-coverage: + @echo "Running frontend tests with coverage..." + @cd archon-ui-main && npm run test:coverage + +# Stop all containers +stop: + @echo "Stopping all containers..." + -@docker-compose down + -@docker-compose -p archon-backend -f docker-compose.backend.yml down + @echo "All services stopped" + +# Clean everything (containers, volumes, node_modules) +clean: + @echo "" + @echo "=========================================" + @echo "⚠️ WARNING: DESTRUCTIVE OPERATION" + @echo "=========================================" + @echo "" + @echo "This command will PERMANENTLY DELETE:" + @echo " • All Docker containers" + @echo " • All Docker volumes (including database data)" + @echo " • All stored documents and embeddings" + @echo " • Docker build cache" + @echo "" + @echo "To proceed, run: make clean-confirm" + @echo "To cancel, press Ctrl+C or do nothing" + @echo "" + +# Actual clean operation (requires explicit confirmation) +clean-confirm: stop + @echo "Cleaning up everything..." + -@docker-compose down -v --remove-orphans + -@docker-compose -p archon-backend -f docker-compose.backend.yml down -v --remove-orphans + @docker system prune -f + @echo "Cleanup complete" + +# Deep clean including dependencies +deep-clean: + @echo "" + @echo "=========================================" + @echo "⚠️ WARNING: COMPLETE RESET" + @echo "=========================================" + @echo "" + @echo "This command will PERMANENTLY DELETE:" + @echo " • Everything from 'make clean'" + @echo " • All npm dependencies (node_modules)" + @echo " • Python virtual environment" + @echo "" + @echo "You will need to run 'make install' after this." + @echo "" + @echo "To proceed, run: make deep-clean-confirm" + @echo "" + +# Actual deep clean operation +deep-clean-confirm: clean-confirm + @echo "Performing deep clean..." + @echo "Please manually delete archon-ui-main/node_modules and python/.venv if needed" + @echo "Deep clean complete. Run 'make install' to reinstall dependencies." + +# Show logs from all services +logs: + @docker-compose -p archon-backend -f docker-compose.backend.yml logs -f + +# Show logs from specific service +logs-%: + @docker-compose -p archon-backend -f docker-compose.backend.yml logs -f $* + +# Show status of all services +status: + @echo "Service Status:" + @echo "===============" + -@docker-compose -p archon-backend -f docker-compose.backend.yml ps + @echo "" + @echo "Check http://localhost:3737 for frontend status" + +# Restart all services +restart: stop dev + +# Lint frontend code +lint-frontend: + @cd archon-ui-main && npm run lint + +# Lint backend code +lint-backend: + @cd python && uv run ruff check + +# Type check backend code +typecheck: + @cd python && uv run mypy src/ + +# Format code +format: + @cd python && uv run ruff format + @cd archon-ui-main && npx prettier --write "src/**/*.{ts,tsx,js,jsx}" + +# Run pre-commit checks +pre-commit: lint-frontend lint-backend typecheck test + @echo "All pre-commit checks passed!" + +# Docker health check +health: + @echo "Checking service health..." + @echo "API Server: http://localhost:8181/health" + @echo "MCP Server: http://localhost:8051/health" + @echo "Agents Service: http://localhost:8052/health" + @echo "Frontend: http://localhost:3737" + +# Watch backend logs +watch-backend: + @docker-compose -p archon-backend -f docker-compose.backend.yml logs -f backend-server + +# Watch MCP logs +watch-mcp: + @docker-compose -p archon-backend -f docker-compose.backend.yml logs -f backend-mcp + +# Watch agents logs +watch-agents: + @docker-compose -p archon-backend -f docker-compose.backend.yml logs -f backend-agents + +# Open shell in backend container +shell-backend: + @docker-compose -p archon-backend -f docker-compose.backend.yml exec backend-server /bin/sh + +# Open shell in MCP container +shell-mcp: + @docker-compose -p archon-backend -f docker-compose.backend.yml exec backend-mcp /bin/sh + +# Run database migrations +migrate: + @echo "Running database migrations..." + @cd python && uv run python -m src.server.db.migrate + +# Backup database +backup-db: + @echo "Creating database backup..." + @docker-compose -p archon-backend -f docker-compose.backend.yml exec backend-server python -m src.server.db.backup + +.DEFAULT_GOAL := help \ No newline at end of file diff --git a/README.md b/README.md index 43e83bdc39..c5b41fa522 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ This new vision for Archon replaces the old one (the agenteer). Archon used to b - [Docker Desktop](https://www.docker.com/products/docker-desktop/) - [Supabase](https://supabase.com/) account (free tier or local Supabase both work) - [OpenAI API key](https://platform.openai.com/api-keys) (Gemini and Ollama are supported too!) +- [Make](https://www.gnu.org/software/make/) (see [Installing Make](#installing-make) below) ### Setup Instructions @@ -64,12 +65,22 @@ This new vision for Archon replaces the old one (the agenteer). Archon used to b 3. **Database Setup**: In your [Supabase project](https://supabase.com/dashboard) SQL Editor, copy, paste, and execute the contents of `migration/complete_setup.sql` -4. **Start Services**: +4. **Start Services** (choose one): + + **Option A: Hybrid Development Mode (Recommended for Development)** + ```bash + make dev + ``` + This runs backend services in Docker and frontend locally with hot module replacement for instant updates. + + **Option B: Full Docker Mode** ```bash + make prod + # or docker-compose up --build -d ``` - This starts the core microservices: + This starts all core microservices in Docker: - **Server**: Core API and business logic (Port: 8181) - **MCP Server**: Protocol interface for AI clients (Port: 8051) - **Agents (coming soon!)**: AI operations and streaming (Port: 8052) @@ -82,6 +93,19 @@ This new vision for Archon replaces the old one (the agenteer). Archon used to b - Go to **Settings** → Select your LLM/embedding provider and set the API key (OpenAI is default) - Test by uploading a document or crawling a website +### 🚀 Quick Command Reference + +| Command | Description | +|---------|-------------| +| `make dev` | Start hybrid dev environment (backend in Docker, frontend local) | +| `make prod` | Start production environment (all in Docker) | +| `make install` | Install all dependencies | +| `make test` | Run all tests | +| `make stop` | Stop all services | +| `make logs` | View service logs | +| `make status` | Check service status | +| `make help` | Show all available commands | + ## 🔄 Database Reset (Start Fresh if Needed) If you need to completely reset your database and start fresh: @@ -108,6 +132,38 @@ The reset script safely removes all tables, functions, triggers, and policies wi +## 🛠️ Installing Make + +Make is required for the development workflow. Installation varies by platform: + +### Windows +```bash +# Option 1: Using Chocolatey +choco install make + +# Option 2: Using Scoop +scoop install make + +# Option 3: Using WSL2 +wsl --install +# Then in WSL: sudo apt-get install make +``` + +### macOS +```bash +# Make comes pre-installed on macOS +# If needed: brew install make +``` + +### Linux +```bash +# Debian/Ubuntu +sudo apt-get install make + +# RHEL/CentOS/Fedora +sudo yum install make +``` + ## ⚡ Quick Test Once everything is running: @@ -259,17 +315,99 @@ After changing hostname or ports: ## 🔧 Development -For development with hot reload: +### Quick Commands + +```bash +# Start hybrid development environment (recommended) +make dev + +# View all available commands +make help + +# Common development commands +make install # Install all dependencies +make test # Run all tests +make lint # Lint frontend and backend +make logs # View service logs +make stop # Stop all services +make clean # Clean up containers and volumes +``` + +### Development Modes +#### Hybrid Mode (Recommended) +Best for active development with instant frontend updates: ```bash -# Backend services (with auto-reload) -docker-compose up archon-server archon-mcp archon-agents --build +make dev +# or +make dev-hybrid +``` +- Backend services run in Docker with hot reload +- Frontend runs locally with HMR (Hot Module Replacement) +- Instant UI updates without Docker rebuilds + +#### Full Docker Mode +For testing production-like environment: +```bash +make dev-docker +``` +- All services run in Docker +- Slower frontend updates (requires rebuild) + +#### Manual Service Control +Start individual services: +```bash +make backend # Start backend services only +make frontend # Start frontend only +``` + +### Testing + +```bash +# Run all tests +make test + +# Frontend tests +make test-frontend +cd archon-ui-main && make test-coverage + +# Backend tests +make test-backend +cd python && make test-coverage +``` + +### Code Quality + +```bash +# Run all checks +make pre-commit + +# Individual checks +make lint-frontend +make lint-backend +make typecheck +``` + +### Service Management + +```bash +# View service status +make status + +# View logs +make logs # All services +make logs-server # Specific service +make watch-backend # Watch backend logs + +# Health check +make health -# Frontend (with hot reload) -cd archon-ui-main && npm run dev +# Restart services +make restart -# Documentation (with hot reload) -cd docs && npm start +# Clean everything +make clean # Remove containers +make deep-clean # Also remove dependencies ``` **Note**: The backend services are configured with `--reload` flag in their uvicorn commands and have source code mounted as volumes for automatic hot reloading when you make changes. diff --git a/dev.bat b/dev.bat deleted file mode 100644 index 290e63c584..0000000000 --- a/dev.bat +++ /dev/null @@ -1,90 +0,0 @@ -@echo off -REM Development environment - Python in Docker, Frontend locally - -echo Starting Archon development environment... -echo Python services in Docker, Frontend running locally - -REM Check if .env file exists -if not exist .env goto no_env_file - -REM Set Docker BuildKit for faster builds -set DOCKER_BUILDKIT=1 -set COMPOSE_DOCKER_CLI_BUILD=1 - -REM Check if production/deployment containers are running and stop them -echo Checking for running production containers... -docker ps | findstr "Archon-Server Archon-UI Archon-MCP Archon-Agents" >nul 2>&1 -if %errorlevel%==0 ( - echo Production containers detected. Stopping them to avoid port conflicts... - docker-compose down - echo Production containers stopped. - echo. -) - -REM Check if backend containers are already running -docker ps | findstr "Archon-Backend-Server" >nul 2>&1 -if %errorlevel%==0 goto containers_running - -REM Check if backend containers exist but are stopped -docker ps -a | findstr "Archon-Backend-Server" >nul 2>&1 -if %errorlevel%==0 goto start_existing - -:build_new -echo Building backend containers for first time... -docker-compose -p archon-backend -f docker-compose.backend.yml up -d --build -goto wait_for_services - -:start_existing -echo Starting existing backend containers... -docker-compose -p archon-backend -f docker-compose.backend.yml start -goto wait_for_services - -:containers_running -echo Backend containers already running. No rebuild needed. - -:wait_for_services -REM Wait for backend services to be ready -echo Waiting for backend services... -timeout /t 3 /nobreak > nul - -REM Check backend health -docker-compose -p archon-backend -f docker-compose.backend.yml ps - -echo. -echo Backend services started in Docker! -echo. -echo Starting frontend locally... -echo. - -REM Start frontend locally in a new window -cd archon-ui-main -start "Archon Frontend" cmd /k "npm run dev" -cd .. - -echo. -echo =================================================== -echo Development Environment Ready! -echo =================================================== -echo. -echo Backend Services in Docker: -echo API Server: http://localhost:8181 -echo MCP Server: http://localhost:8051 -echo Agents Service: http://localhost:8052 -echo. -echo Frontend running locally: -echo UI with HMR: http://localhost:3737 -echo. -echo Commands: -echo Backend logs: docker-compose -p archon-backend -f docker-compose.backend.yml logs -f -echo Stop backend: docker-compose -p archon-backend -f docker-compose.backend.yml stop -echo Remove backend: docker-compose -p archon-backend -f docker-compose.backend.yml down -echo. -echo Frontend is running in a separate window with full HMR support! -echo Edit files in archon-ui-main/ and see instant updates. -goto end - -:no_env_file -echo ERROR: .env file not found. Please copy .env.example to .env and configure it. -exit /b 1 - -:end \ No newline at end of file From ccd464cdfa00cf6b6388ca50438591793d3be985 Mon Sep 17 00:00:00 2001 From: Zak Stam Date: Thu, 21 Aug 2025 18:58:54 +0300 Subject: [PATCH 03/15] Enhance development environment: add environment variable checks and update test commands for frontend and backend --- Makefile | 6 +++++- README.md | 7 ++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 5e6776a08c..d18377c220 100644 --- a/Makefile +++ b/Makefile @@ -44,11 +44,15 @@ install: check-frontend-deps: @cd archon-ui-main && npm install --silent +# Verify required env vars exist - using Node.js for cross-platform compatibility +check-env: + @node -e "const fs=require('fs'); if(!fs.existsSync('.env')){console.error('ERROR: .env file not found! Create one from .env.example');process.exit(1);} const env=fs.readFileSync('.env','utf8'); const missing=[]; if(!env.includes('SUPABASE_URL=')){missing.push('SUPABASE_URL');} if(!env.includes('SUPABASE_SERVICE_KEY=')){missing.push('SUPABASE_SERVICE_KEY');} if(missing.length>0){console.error('ERROR: Missing required env vars: '+missing.join(', '));process.exit(1);} console.log('Environment OK: SUPABASE_URL and SUPABASE_SERVICE_KEY found.');" + # Default dev target - hybrid mode dev: dev-hybrid # Hybrid development - backend in Docker, frontend local -dev-hybrid: stop-prod check-frontend-deps +dev-hybrid: stop-prod check-env check-frontend-deps @echo "Starting hybrid development environment..." @echo "Backend services in Docker, Frontend running locally" @docker-compose -p archon-backend -f docker-compose.backend.yml up -d --build diff --git a/README.md b/README.md index c5b41fa522..e9e015570f 100644 --- a/README.md +++ b/README.md @@ -369,11 +369,12 @@ make test # Frontend tests make test-frontend -cd archon-ui-main && make test-coverage +cd archon-ui-main && npm run test:coverage -# Backend tests +# Backend tests make test-backend -cd python && make test-coverage +# (Optional) run directly via uv +cd python && uv run pytest ``` ### Code Quality From 97f4e9b525906a90f0e1370e7f80cf27be0a74cc Mon Sep 17 00:00:00 2001 From: Rasmus Widing Date: Fri, 22 Aug 2025 10:24:15 +0300 Subject: [PATCH 04/15] Improve development environment with Docker Compose profiles This commit enhances the development workflow by replacing the separate docker-compose.backend.yml file with Docker Compose profiles, fixing critical service discovery issues, and adding comprehensive developer tooling through an improved Makefile system. Key improvements: - Replace docker-compose.backend.yml with cleaner profile approach - Fix service discovery by maintaining consistent container names - Fix port mappings (3737:3737 instead of 3737:5173) - Add make doctor for environment validation - Fix port configuration and frontend HMR - Improve error handling with .SHELLFLAGS in Makefile - Add comprehensive port configuration via environment variables - Simplify make dev-local to only run essential services - Add logging directory creation for local development - Document profile strategy in docker-compose.yml These changes provide three flexible development modes: - Hybrid mode (default): Backend in Docker, frontend local with HMR - Docker mode: Everything in Docker for production-like testing - Local mode: API server and UI run locally Co-authored-by: Zak Stam --- .env.example | 6 ++ .gitignore | 2 + Makefile | 111 +++++++++++++++++++++++++------ archon-ui-main/Dockerfile | 8 +-- archon-ui-main/src/config/api.ts | 5 +- archon-ui-main/vite.config.ts | 2 +- docker-compose.backend.yml | 109 ------------------------------ docker-compose.yml | 14 +++- 8 files changed, 120 insertions(+), 137 deletions(-) delete mode 100644 docker-compose.backend.yml diff --git a/.env.example b/.env.example index f2cf73e586..2ce0a061fc 100644 --- a/.env.example +++ b/.env.example @@ -23,6 +23,12 @@ ARCHON_AGENTS_PORT=8052 ARCHON_UI_PORT=3737 ARCHON_DOCS_PORT=3838 +# Frontend-specific port configuration (optional) +# VITE_ARCHON_SERVER_PORT - Override the API server port for frontend only +# This is useful when the frontend needs to connect to a different port than ARCHON_SERVER_PORT +# If not set, frontend will use ARCHON_SERVER_PORT or default to 8181 +# VITE_ARCHON_SERVER_PORT=8181 + # Embedding Configuration # Dimensions for embedding vectors (1536 for OpenAI text-embedding-3-small) EMBEDDING_DIMENSIONS=1536 diff --git a/.gitignore b/.gitignore index fbeaa6d47d..189523a6dc 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ __pycache__ .serena .claude/settings.local.json PRPs/local + +logs diff --git a/Makefile b/Makefile index d18377c220..4d9e59dc73 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,10 @@ # Archon Development Makefile # Cross-platform development environment management +# Shell flags for better error handling +SHELL := /bin/bash +.SHELLFLAGS := -ec + .PHONY: help dev dev-hybrid dev-docker prod build test clean clean-confirm deep-clean deep-clean-confirm stop logs status install check-env # Default target - show help @@ -16,9 +20,11 @@ help: @echo "Development Modes:" @echo " make dev-hybrid - Backend in Docker, frontend locally with HMR (default)" @echo " make dev-docker - Everything in Docker (slower frontend updates)" + @echo " make dev-local - API server and frontend locally (MCP/Agents stay in Docker)" @echo "" @echo "Management:" - @echo " make stop - Stop all running containers" + @echo " make stop - Stop all Docker containers" + @echo " make stop-local - Stop all local services" @echo " make clean - Stop and remove all containers and volumes" @echo " make logs - Show logs from all services" @echo " make status - Show status of all services" @@ -28,6 +34,9 @@ help: @echo " make test-frontend - Run frontend tests only" @echo " make test-backend - Run backend tests only" @echo "" + @echo "Utilities:" + @echo " make doctor - Check development environment setup" + @echo "" @echo "Individual Services:" @echo " make frontend - Start frontend only (local)" @echo " make backend - Start backend services only (Docker)" @@ -55,7 +64,7 @@ dev: dev-hybrid dev-hybrid: stop-prod check-env check-frontend-deps @echo "Starting hybrid development environment..." @echo "Backend services in Docker, Frontend running locally" - @docker-compose -p archon-backend -f docker-compose.backend.yml up -d --build + @LOG_LEVEL=DEBUG docker-compose --profile backend up -d --build @echo "" @echo "=====================================================" @echo "Development Environment Ready!" @@ -78,21 +87,56 @@ dev-hybrid: stop-prod check-env check-frontend-deps # Full Docker development dev-docker: @echo "Starting full Docker development environment..." - docker-compose up -d --build + docker-compose --profile full up -d --build @echo "All services running in Docker" @echo "UI available at: http://localhost:3737" +# Full local development - API server and frontend only (MCP/Agents run in Docker) +dev-local: check-env install + @echo "Starting local development environment..." + @echo "API Server and Frontend running locally" + @echo "Note: MCP Server and Agents Service should run in Docker if needed" + @echo "" + @echo "======================================================" + @echo "Local Development Environment" + @echo "======================================================" + @echo "" + @echo "Starting API Server on port 8181..." + @mkdir -p logs + @cd python && uv run python -m src.server.main > ../logs/api-server.log 2>&1 & + @sleep 3 + @echo "" + @echo "Backend service started!" + @echo "" + @echo "API Server: http://localhost:8181" + @echo "" + @echo "Log file: ./logs/api-server.log" + @echo "" + @echo "Starting frontend on port 3737..." + @echo "" + @echo "To run MCP/Agents in Docker, use:" + @echo " docker-compose --profile backend up -d archon-mcp archon-agents" + @echo "" + @cd archon-ui-main && npm run dev + +# Stop local services +stop-local: + @echo "Stopping local services..." + @pkill -f "python -m src.server.main" || true + @pkill -f "npx vite" || true + @echo "Local services stopped" + # Production environment prod: @echo "Starting production environment..." - docker-compose up -d --build + docker-compose --profile full up -d --build @echo "Production environment started" @echo "UI available at: http://localhost:3737" # Start backend services only backend: @echo "Starting backend services in Docker..." - docker-compose -p archon-backend -f docker-compose.backend.yml up -d --build + docker-compose --profile backend up -d --build # Start frontend only (foreground) frontend: @@ -101,15 +145,13 @@ frontend: # Stop production containers if running stop-prod: @echo "Checking for running production containers..." - -@docker-compose down - -@docker-compose -p archon-backend -f docker-compose.backend.yml down + @docker-compose down 2>/dev/null || true @echo "Containers stopped" # Build all Docker images build: @echo "Building all Docker images..." - docker-compose build - docker-compose -f docker-compose.backend.yml build + docker-compose --profile full build # Run all tests test: test-frontend test-backend @@ -132,8 +174,7 @@ test-coverage: # Stop all containers stop: @echo "Stopping all containers..." - -@docker-compose down - -@docker-compose -p archon-backend -f docker-compose.backend.yml down + @docker-compose down || true @echo "All services stopped" # Clean everything (containers, volumes, node_modules) @@ -157,7 +198,6 @@ clean: clean-confirm: stop @echo "Cleaning up everything..." -@docker-compose down -v --remove-orphans - -@docker-compose -p archon-backend -f docker-compose.backend.yml down -v --remove-orphans @docker system prune -f @echo "Cleanup complete" @@ -186,17 +226,17 @@ deep-clean-confirm: clean-confirm # Show logs from all services logs: - @docker-compose -p archon-backend -f docker-compose.backend.yml logs -f + @docker-compose logs -f # Show logs from specific service logs-%: - @docker-compose -p archon-backend -f docker-compose.backend.yml logs -f $* + @docker-compose logs -f $* # Show status of all services status: @echo "Service Status:" @echo "===============" - -@docker-compose -p archon-backend -f docker-compose.backend.yml ps + -@docker-compose ps @echo "" @echo "Check http://localhost:3737 for frontend status" @@ -234,23 +274,23 @@ health: # Watch backend logs watch-backend: - @docker-compose -p archon-backend -f docker-compose.backend.yml logs -f backend-server + @docker-compose logs -f archon-server # Watch MCP logs watch-mcp: - @docker-compose -p archon-backend -f docker-compose.backend.yml logs -f backend-mcp + @docker-compose logs -f archon-mcp # Watch agents logs watch-agents: - @docker-compose -p archon-backend -f docker-compose.backend.yml logs -f backend-agents + @docker-compose logs -f archon-agents # Open shell in backend container shell-backend: - @docker-compose -p archon-backend -f docker-compose.backend.yml exec backend-server /bin/sh + @docker-compose exec archon-server /bin/sh # Open shell in MCP container shell-mcp: - @docker-compose -p archon-backend -f docker-compose.backend.yml exec backend-mcp /bin/sh + @docker-compose exec archon-mcp /bin/sh # Run database migrations migrate: @@ -260,6 +300,35 @@ migrate: # Backup database backup-db: @echo "Creating database backup..." - @docker-compose -p archon-backend -f docker-compose.backend.yml exec backend-server python -m src.server.db.backup + @docker-compose exec archon-server python -m src.server.db.backup + +# Development environment validation +doctor: + @echo "🔍 Checking development environment..." + @echo "" + @echo "=== Required Tools ===" + @command -v docker >/dev/null 2>&1 && echo "✅ Docker: $(shell docker --version | cut -d' ' -f3)" || echo "❌ Docker: Not installed" + @command -v docker-compose >/dev/null 2>&1 && echo "✅ Docker Compose: $(shell docker-compose --version | cut -d' ' -f4)" || echo "❌ Docker Compose: Not installed" + @command -v node >/dev/null 2>&1 && echo "✅ Node.js: $(shell node --version)" || echo "❌ Node.js: Not installed" + @command -v npm >/dev/null 2>&1 && echo "✅ npm: $(shell npm --version)" || echo "❌ npm: Not installed" + @command -v python3 >/dev/null 2>&1 && echo "✅ Python: $(shell python3 --version | cut -d' ' -f2)" || echo "❌ Python: Not installed" + @command -v uv >/dev/null 2>&1 && echo "✅ uv: $(shell uv --version | cut -d' ' -f2)" || echo "❌ uv: Not installed (needed for local development)" + @command -v make >/dev/null 2>&1 && echo "✅ Make: $(shell make --version | head -1 | cut -d' ' -f3)" || echo "❌ Make: Not installed" + @echo "" + @echo "=== Environment Variables ===" + @test -f .env && echo "✅ .env file exists" || echo "❌ .env file missing (copy from .env.example)" + @test -f .env && grep -q "SUPABASE_URL=" .env && echo "✅ SUPABASE_URL is set" || echo "❌ SUPABASE_URL not set" + @test -f .env && grep -q "SUPABASE_SERVICE_KEY=" .env && echo "✅ SUPABASE_SERVICE_KEY is set" || echo "❌ SUPABASE_SERVICE_KEY not set" + @echo "" + @echo "=== Port Availability ===" + @lsof -i :8181 >/dev/null 2>&1 && echo "⚠️ Port 8181 (API Server) is in use" || echo "✅ Port 8181 (API Server) is available" + @lsof -i :8051 >/dev/null 2>&1 && echo "⚠️ Port 8051 (MCP Server) is in use" || echo "✅ Port 8051 (MCP Server) is available" + @lsof -i :8052 >/dev/null 2>&1 && echo "⚠️ Port 8052 (Agents) is in use" || echo "✅ Port 8052 (Agents) is available" + @lsof -i :3737 >/dev/null 2>&1 && echo "⚠️ Port 3737 (Frontend) is in use" || echo "✅ Port 3737 (Frontend) is available" + @echo "" + @echo "=== Docker Status ===" + @docker info >/dev/null 2>&1 && echo "✅ Docker daemon is running" || echo "❌ Docker daemon is not running" + @echo "" + @echo "🏁 Environment check complete!" .DEFAULT_GOAL := help \ No newline at end of file diff --git a/archon-ui-main/Dockerfile b/archon-ui-main/Dockerfile index a413744aed..e0f6dbf692 100644 --- a/archon-ui-main/Dockerfile +++ b/archon-ui-main/Dockerfile @@ -18,8 +18,8 @@ RUN mkdir -p /app/coverage && chmod 777 /app/coverage # Copy source code COPY . . -# Expose Vite's default port -EXPOSE 5173 +# Expose the port configured in package.json (3737) +EXPOSE 3737 -# Start Vite dev server with host binding for Docker -CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"] \ No newline at end of file +# Start Vite dev server (already configured with --port 3737 --host in package.json) +CMD ["npm", "run", "dev"] \ No newline at end of file diff --git a/archon-ui-main/src/config/api.ts b/archon-ui-main/src/config/api.ts index 437e1126f5..1efc952d2e 100644 --- a/archon-ui-main/src/config/api.ts +++ b/archon-ui-main/src/config/api.ts @@ -21,7 +21,10 @@ export function getApiUrl(): string { const protocol = window.location.protocol; const host = window.location.hostname; // Try VITE_ prefixed env var first, then fallback to default - const port = import.meta.env.VITE_ARCHON_SERVER_PORT || '8181'; + const port = import.meta.env.VITE_ARCHON_SERVER_PORT || (() => { + console.info('[Archon] Using default ARCHON_SERVER_PORT: 8181'); + return '8181'; + })(); return `${protocol}//${host}:${port}`; } diff --git a/archon-ui-main/vite.config.ts b/archon-ui-main/vite.config.ts index 0c812614b5..4a6264b1e9 100644 --- a/archon-ui-main/vite.config.ts +++ b/archon-ui-main/vite.config.ts @@ -278,7 +278,7 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => { ], server: { host: '0.0.0.0', // Listen on all network interfaces with explicit IP - port: 5173, // Match the port expected in Docker + port: parseInt(process.env.ARCHON_UI_PORT || env.ARCHON_UI_PORT || '3737'), // Use configurable port strictPort: true, // Exit if port is in use proxy: { '/api': { diff --git a/docker-compose.backend.yml b/docker-compose.backend.yml deleted file mode 100644 index 460b5890ac..0000000000 --- a/docker-compose.backend.yml +++ /dev/null @@ -1,109 +0,0 @@ -# Backend-only services for hybrid development -# Python services run in Docker, frontend runs locally - -services: - # Backend Server Service (FastAPI + Socket.IO) - backend-server: - build: - context: ./python - dockerfile: Dockerfile.server - args: - BUILDKIT_INLINE_CACHE: 1 - ARCHON_SERVER_PORT: ${ARCHON_SERVER_PORT:-8181} - container_name: Archon-Backend-Server - ports: - - "${ARCHON_SERVER_PORT:-8181}:${ARCHON_SERVER_PORT:-8181}" - environment: - - SUPABASE_URL=${SUPABASE_URL} - - SUPABASE_SERVICE_KEY=${SUPABASE_SERVICE_KEY} - - OPENAI_API_KEY=${OPENAI_API_KEY:-} - - LOGFIRE_TOKEN=${LOGFIRE_TOKEN:-} - - SERVICE_DISCOVERY_MODE=docker_compose - - LOG_LEVEL=${LOG_LEVEL:-DEBUG} - - ARCHON_SERVER_PORT=${ARCHON_SERVER_PORT:-8181} - - ARCHON_MCP_PORT=${ARCHON_MCP_PORT:-8051} - - ARCHON_AGENTS_PORT=${ARCHON_AGENTS_PORT:-8052} - - PYTHONUNBUFFERED=1 - - PYTHONDONTWRITEBYTECODE=1 - networks: - - backend-network - volumes: - - /var/run/docker.sock:/var/run/docker.sock - - ./python/src:/app/src # Hot reload for Python - - ./python/tests:/app/tests - command: ["python", "-m", "uvicorn", "src.server.main:socket_app", "--host", "0.0.0.0", "--port", "${ARCHON_SERVER_PORT:-8181}", "--reload"] - healthcheck: - test: ["CMD", "sh", "-c", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:${ARCHON_SERVER_PORT:-8181}/health')\""] - interval: 10s - timeout: 5s - retries: 3 - start_period: 20s - - # MCP Server Service - backend-mcp: - build: - context: ./python - dockerfile: Dockerfile.mcp - args: - BUILDKIT_INLINE_CACHE: 1 - ARCHON_MCP_PORT: ${ARCHON_MCP_PORT:-8051} - container_name: Archon-Backend-MCP - ports: - - "${ARCHON_MCP_PORT:-8051}:${ARCHON_MCP_PORT:-8051}" - environment: - - SUPABASE_URL=${SUPABASE_URL} - - SUPABASE_SERVICE_KEY=${SUPABASE_SERVICE_KEY} - - LOGFIRE_TOKEN=${LOGFIRE_TOKEN:-} - - SERVICE_DISCOVERY_MODE=docker_compose - - TRANSPORT=sse - - LOG_LEVEL=${LOG_LEVEL:-DEBUG} - - API_SERVICE_URL=http://backend-server:${ARCHON_SERVER_PORT:-8181} - - AGENTS_SERVICE_URL=http://backend-agents:${ARCHON_AGENTS_PORT:-8052} - - ARCHON_MCP_PORT=${ARCHON_MCP_PORT:-8051} - - ARCHON_SERVER_PORT=${ARCHON_SERVER_PORT:-8181} - - ARCHON_AGENTS_PORT=${ARCHON_AGENTS_PORT:-8052} - networks: - - backend-network - depends_on: - - backend-server - - backend-agents - healthcheck: - test: ["CMD", "sh", "-c", "python -c \"import socket; s=socket.socket(); s.connect(('localhost', ${ARCHON_MCP_PORT:-8051})); s.close()\""] - interval: 10s - timeout: 5s - retries: 3 - start_period: 30s - - # Agents Service - backend-agents: - build: - context: ./python - dockerfile: Dockerfile.agents - args: - BUILDKIT_INLINE_CACHE: 1 - ARCHON_AGENTS_PORT: ${ARCHON_AGENTS_PORT:-8052} - container_name: Archon-Backend-Agents - ports: - - "${ARCHON_AGENTS_PORT:-8052}:${ARCHON_AGENTS_PORT:-8052}" - environment: - - SUPABASE_URL=${SUPABASE_URL} - - SUPABASE_SERVICE_KEY=${SUPABASE_SERVICE_KEY} - - OPENAI_API_KEY=${OPENAI_API_KEY:-} - - LOGFIRE_TOKEN=${LOGFIRE_TOKEN:-} - - SERVICE_DISCOVERY_MODE=docker_compose - - LOG_LEVEL=${LOG_LEVEL:-DEBUG} - - ARCHON_AGENTS_PORT=${ARCHON_AGENTS_PORT:-8052} - - PYTHONUNBUFFERED=1 - - PYTHONDONTWRITEBYTECODE=1 - networks: - - backend-network - healthcheck: - test: ["CMD", "sh", "-c", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:${ARCHON_AGENTS_PORT:-8052}/health')\""] - interval: 10s - timeout: 5s - retries: 3 - start_period: 20s - -networks: - backend-network: - driver: bridge \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 59bd1e2302..fc69874e0e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,15 @@ +# Docker Compose Profiles Strategy: +# - "backend": Starts only backend services (server, mcp, agents) for hybrid development +# - "frontend": Starts only the frontend UI service +# - "full": Starts all services for complete Docker deployment +# Use --profile flag with docker-compose to control which services start: +# docker-compose --profile backend up # Backend only for hybrid dev +# docker-compose --profile full up # Everything in Docker + services: # Server Service (FastAPI + Socket.IO + Crawling) archon-server: + profiles: ["backend", "full"] build: context: ./python dockerfile: Dockerfile.server @@ -36,6 +45,7 @@ services: # Lightweight MCP Server Service (HTTP-based) archon-mcp: + profiles: ["backend", "full"] build: context: ./python dockerfile: Dockerfile.mcp @@ -72,6 +82,7 @@ services: # AI Agents Service (ML/Reranking) archon-agents: + profiles: ["backend", "full"] build: context: ./python dockerfile: Dockerfile.agents @@ -100,10 +111,11 @@ services: # Frontend frontend: + profiles: ["frontend", "full"] build: ./archon-ui-main container_name: Archon-UI ports: - - "${ARCHON_UI_PORT:-3737}:5173" + - "${ARCHON_UI_PORT:-3737}:3737" environment: - VITE_API_URL=http://${HOST:-localhost}:${ARCHON_SERVER_PORT:-8181} - ARCHON_SERVER_PORT=${ARCHON_SERVER_PORT:-8181} From 57994ff939604bdf9a64c866c2ee7fe1a4d43918 Mon Sep 17 00:00:00 2001 From: Rasmus Widing Date: Fri, 22 Aug 2025 10:35:40 +0300 Subject: [PATCH 05/15] Fix make stop command to properly handle Docker Compose profiles The stop command now explicitly specifies all profiles to ensure all containers are stopped regardless of how they were started. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4d9e59dc73..542d1af96a 100644 --- a/Makefile +++ b/Makefile @@ -174,7 +174,7 @@ test-coverage: # Stop all containers stop: @echo "Stopping all containers..." - @docker-compose down || true + @docker-compose --profile backend --profile frontend --profile full down || true @echo "All services stopped" # Clean everything (containers, volumes, node_modules) From 5c4861b9ebba5af201c468bf0313a329d51041fb Mon Sep 17 00:00:00 2001 From: Rasmus Widing Date: Fri, 22 Aug 2025 10:43:33 +0300 Subject: [PATCH 06/15] Fix README to document correct make commands - Changed 'make lint' to 'make lint-frontend' and 'make lint-backend' - Removed non-existent 'make logs-server' command - Added 'make watch-mcp' and 'make watch-agents' commands - All documented make commands now match what's available in Makefile --- README.md | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c2c7701d08..929b5bfb82 100644 --- a/README.md +++ b/README.md @@ -342,7 +342,8 @@ make help # Common development commands make install # Install all dependencies make test # Run all tests -make lint # Lint frontend and backend +make lint-frontend # Lint frontend code +make lint-backend # Lint backend code make logs # View service logs make stop # Stop all services make clean # Clean up containers and volumes @@ -361,6 +362,12 @@ make dev-hybrid - Frontend runs locally with HMR (Hot Module Replacement) - Instant UI updates without Docker rebuilds +**Security Note**: The frontend dev server uses `--host` flag to allow network access. This is useful for: +- Testing on different devices on your network +- Accessing the UI from Docker containers + +However, this exposes the dev server to your local network. In production or on untrusted networks, ensure proper firewall rules are in place. + #### Full Docker Mode For testing production-like environment: ```bash @@ -412,8 +419,9 @@ make status # View logs make logs # All services -make logs-server # Specific service make watch-backend # Watch backend logs +make watch-mcp # Watch MCP logs +make watch-agents # Watch agents logs # Health check make health @@ -428,6 +436,83 @@ make deep-clean # Also remove dependencies **Note**: The backend services are configured with `--reload` flag in their uvicorn commands and have source code mounted as volumes for automatic hot reloading when you make changes. +## 🔍 Troubleshooting + +### Common Issues and Solutions + +#### Port Conflicts +If you see "Port already in use" errors: +```bash +# Check what's using a port (e.g., 3737) +lsof -i :3737 + +# Stop all containers and local services +make stop +make stop-local + +# Or kill specific process +kill +``` + +#### Docker Permission Issues (Linux) +If you encounter permission errors with Docker: +```bash +# Add your user to the docker group +sudo usermod -aG docker $USER + +# Log out and back in, or run +newgrp docker +``` + +#### Windows-Specific Issues +- **Make not found**: Install Make via Chocolatey, Scoop, or WSL2 (see [Installing Make](#installing-make)) +- **Line ending issues**: Configure Git to use LF endings: + ```bash + git config --global core.autocrlf false + ``` + +#### Environment Variables Not Loading +```bash +# Verify .env file exists and has required variables +make doctor + +# Check specific variables +grep SUPABASE_URL .env +grep SUPABASE_SERVICE_KEY .env +``` + +#### Frontend Can't Connect to Backend +- Check backend is running: `curl http://localhost:8181/health` +- Verify port configuration in `.env` +- For custom ports, ensure both `ARCHON_SERVER_PORT` and `VITE_ARCHON_SERVER_PORT` are set + +#### Docker Compose Hangs +If `docker-compose` commands hang: +```bash +# Reset Docker Compose +docker-compose down --remove-orphans +docker system prune -f + +# Restart Docker Desktop (if applicable) +``` + +#### Hot Reload Not Working +- **Frontend**: Ensure you're running in hybrid mode (`make dev-hybrid`) for best HMR experience +- **Backend**: Check that volumes are mounted correctly in `docker-compose.yml` +- **File permissions**: On some systems, mounted volumes may have permission issues + +#### Check Your Setup +Run the doctor command to validate your environment: +```bash +make doctor +``` + +This will check: +- Required tools installation +- Environment variables +- Port availability +- Docker daemon status + ## 📈 Progress

From caf4398dc2a6f5525fc812d6def158eee7326f15 Mon Sep 17 00:00:00 2001 From: Rasmus Widing Date: Fri, 22 Aug 2025 11:24:55 +0300 Subject: [PATCH 07/15] fix: Address critical issues from code review #435 - Create robust environment validation script (check-env.js) that properly parses .env files - Fix Docker healthcheck port mismatch (5173 -> 3737) - Remove hard-coded port flags from package.json to allow environment configuration - Fix Docker detection logic using /.dockerenv instead of HOSTNAME - Normalize container names to lowercase (archon-server, archon-mcp, etc.) - Improve stop-local command with port-based fallback for process killing - Fix API configuration fallback chain to include VITE_PORT - Fix Makefile shell variable expansion using runtime evaluation - Update .PHONY targets with comprehensive list - Add --profile flags to Docker Compose commands in README - Add VITE_ARCHON_SERVER_PORT to docker-compose.yml - Add Node.js 18+ to prerequisites - Use dynamic ports in Makefile help messages - Add lint alias combining frontend and backend linting - Update .env.example documentation - Scope .gitignore logs entry to /logs/ Co-Authored-By: Claude --- .env.example | 2 +- .gitignore | 3 +- Makefile | 37 +++++++++------ README.md | 78 ++++++++++++++++++++----------- archon-ui-main/package.json | 2 +- archon-ui-main/src/config/api.ts | 12 +++-- archon-ui-main/vite.config.ts | 2 +- check-env.js | 80 ++++++++++++++++++++++++++++++++ docker-compose.yml | 11 +++-- 9 files changed, 173 insertions(+), 54 deletions(-) create mode 100644 check-env.js diff --git a/.env.example b/.env.example index 4d173e24ec..ca14233df3 100644 --- a/.env.example +++ b/.env.example @@ -39,7 +39,7 @@ ARCHON_DOCS_PORT=3838 # Frontend-specific port configuration (optional) # VITE_ARCHON_SERVER_PORT - Override the API server port for frontend only # This is useful when the frontend needs to connect to a different port than ARCHON_SERVER_PORT -# If not set, frontend will use ARCHON_SERVER_PORT or default to 8181 +# If not set, frontend will use VITE_PORT (if available) or default to 8181 # VITE_ARCHON_SERVER_PORT=8181 # Embedding Configuration diff --git a/.gitignore b/.gitignore index 189523a6dc..bc0c047453 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,4 @@ __pycache__ .serena .claude/settings.local.json PRPs/local - -logs +/logs/ diff --git a/Makefile b/Makefile index 542d1af96a..fe9bbb851b 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,13 @@ SHELL := /bin/bash .SHELLFLAGS := -ec -.PHONY: help dev dev-hybrid dev-docker prod build test clean clean-confirm deep-clean deep-clean-confirm stop logs status install check-env +.PHONY: help dev dev-hybrid dev-docker dev-local prod backend frontend \ + build test test-frontend test-backend test-coverage clean clean-confirm \ + deep-clean deep-clean-confirm stop stop-local stop-prod logs status install \ + install-backend install-frontend check-env check-frontend-deps doctor health \ + lint lint-frontend lint-backend typecheck format pre-commit restart \ + watch-backend watch-mcp watch-agents shell-backend shell-mcp migrate backup-db \ + logs-archon-server logs-archon-mcp logs-archon-agents logs-archon-ui # Default target - show help help: @@ -55,7 +61,7 @@ check-frontend-deps: # Verify required env vars exist - using Node.js for cross-platform compatibility check-env: - @node -e "const fs=require('fs'); if(!fs.existsSync('.env')){console.error('ERROR: .env file not found! Create one from .env.example');process.exit(1);} const env=fs.readFileSync('.env','utf8'); const missing=[]; if(!env.includes('SUPABASE_URL=')){missing.push('SUPABASE_URL');} if(!env.includes('SUPABASE_SERVICE_KEY=')){missing.push('SUPABASE_SERVICE_KEY');} if(missing.length>0){console.error('ERROR: Missing required env vars: '+missing.join(', '));process.exit(1);} console.log('Environment OK: SUPABASE_URL and SUPABASE_SERVICE_KEY found.');" + @node check-env.js # Default dev target - hybrid mode dev: dev-hybrid @@ -71,9 +77,9 @@ dev-hybrid: stop-prod check-env check-frontend-deps @echo "=====================================================" @echo "" @echo "Backend Services in Docker:" - @echo " API Server: http://localhost:8181" - @echo " MCP Server: http://localhost:8051" - @echo " Agents Service: http://localhost:8052" + @echo " API Server: http://localhost:$${ARCHON_SERVER_PORT:-8181}" + @echo " MCP Server: http://localhost:$${ARCHON_MCP_PORT:-8051}" + @echo " Agents Service: http://localhost:$${ARCHON_AGENTS_PORT:-8052}" @echo "" @echo "Starting frontend server..." @echo "" @@ -123,7 +129,9 @@ dev-local: check-env install stop-local: @echo "Stopping local services..." @pkill -f "python -m src.server.main" || true - @pkill -f "npx vite" || true + @pkill -f "vite" || true + @lsof -ti:3737 | xargs kill -9 2>/dev/null || true + @lsof -ti:8181 | xargs kill -9 2>/dev/null || true @echo "Local services stopped" # Production environment @@ -251,6 +259,9 @@ lint-frontend: lint-backend: @cd python && uv run ruff check +# Lint all code (frontend and backend) +lint: lint-frontend lint-backend + # Type check backend code typecheck: @cd python && uv run mypy src/ @@ -307,13 +318,13 @@ doctor: @echo "🔍 Checking development environment..." @echo "" @echo "=== Required Tools ===" - @command -v docker >/dev/null 2>&1 && echo "✅ Docker: $(shell docker --version | cut -d' ' -f3)" || echo "❌ Docker: Not installed" - @command -v docker-compose >/dev/null 2>&1 && echo "✅ Docker Compose: $(shell docker-compose --version | cut -d' ' -f4)" || echo "❌ Docker Compose: Not installed" - @command -v node >/dev/null 2>&1 && echo "✅ Node.js: $(shell node --version)" || echo "❌ Node.js: Not installed" - @command -v npm >/dev/null 2>&1 && echo "✅ npm: $(shell npm --version)" || echo "❌ npm: Not installed" - @command -v python3 >/dev/null 2>&1 && echo "✅ Python: $(shell python3 --version | cut -d' ' -f2)" || echo "❌ Python: Not installed" - @command -v uv >/dev/null 2>&1 && echo "✅ uv: $(shell uv --version | cut -d' ' -f2)" || echo "❌ uv: Not installed (needed for local development)" - @command -v make >/dev/null 2>&1 && echo "✅ Make: $(shell make --version | head -1 | cut -d' ' -f3)" || echo "❌ Make: Not installed" + @command -v docker >/dev/null 2>&1 && echo "✅ Docker: $$(docker --version | cut -d' ' -f3)" || echo "❌ Docker: Not installed" + @command -v docker-compose >/dev/null 2>&1 && echo "✅ Docker Compose: $$(docker-compose --version | cut -d' ' -f4)" || echo "❌ Docker Compose: Not installed" + @command -v node >/dev/null 2>&1 && echo "✅ Node.js: $$(node --version)" || echo "❌ Node.js: Not installed" + @command -v npm >/dev/null 2>&1 && echo "✅ npm: $$(npm --version)" || echo "❌ npm: Not installed" + @command -v python3 >/dev/null 2>&1 && echo "✅ Python: $$(python3 --version | cut -d' ' -f2)" || echo "❌ Python: Not installed" + @command -v uv >/dev/null 2>&1 && echo "✅ uv: $$(uv --version | cut -d' ' -f2)" || echo "❌ uv: Not installed (needed for local development)" + @command -v make >/dev/null 2>&1 && echo "✅ Make: $$(make --version | head -1 | cut -d' ' -f3)" || echo "❌ Make: Not installed" @echo "" @echo "=== Environment Variables ===" @test -f .env && echo "✅ .env file exists" || echo "❌ .env file missing (copy from .env.example)" diff --git a/README.md b/README.md index 929b5bfb82..40a754fdf1 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ This new vision for Archon replaces the old one (the agenteer). Archon used to b ### Prerequisites - [Docker Desktop](https://www.docker.com/products/docker-desktop/) +- [Node.js 18+](https://nodejs.org/) (for hybrid development mode) - [Supabase](https://supabase.com/) account (free tier or local Supabase both work) - [OpenAI API key](https://platform.openai.com/api-keys) (Gemini and Ollama are supported too!) - [Make](https://www.gnu.org/software/make/) (see [Installing Make](#installing-make) below) @@ -73,19 +74,14 @@ This new vision for Archon replaces the old one (the agenteer). Archon used to b 4. **Start Services** (choose one): - **Option A: Hybrid Development Mode (Recommended for Development)** - ```bash - make dev - ``` - This runs backend services in Docker and frontend locally with hot module replacement for instant updates. + **Option A: Full Docker Mode (Recommended for Normal Archon Usage)** - **Option B: Full Docker Mode** ```bash make prod # or - docker-compose up --build -d + docker-compose --profile full up --build -d ``` - + This starts all core microservices in Docker: - **Server**: Core API and business logic (Port: 8181) - **MCP Server**: Protocol interface for AI clients (Port: 8051) @@ -94,6 +90,14 @@ This new vision for Archon replaces the old one (the agenteer). Archon used to b Ports are configurable in your .env as well! + **Option B: Hybrid Development Mode (Recommended for Development)** + + ```bash + make dev + ``` + + This runs backend services in Docker and frontend locally with hot module replacement for instant updates. + 5. **Configure API Keys**: - Open http://localhost:3737 - Go to **Settings** → Select your LLM/embedding provider and set the API key (OpenAI is default) @@ -101,16 +105,16 @@ This new vision for Archon replaces the old one (the agenteer). Archon used to b ### 🚀 Quick Command Reference -| Command | Description | -|---------|-------------| -| `make dev` | Start hybrid dev environment (backend in Docker, frontend local) | -| `make prod` | Start production environment (all in Docker) | -| `make install` | Install all dependencies | -| `make test` | Run all tests | -| `make stop` | Stop all services | -| `make logs` | View service logs | -| `make status` | Check service status | -| `make help` | Show all available commands | +| Command | Description | +| -------------- | ---------------------------------------------------------------- | +| `make dev` | Start hybrid dev environment (backend in Docker, frontend local) | +| `make prod` | Start production environment (all in Docker) | +| `make install` | Install all dependencies | +| `make test` | Run all tests | +| `make stop` | Stop all services | +| `make logs` | View service logs | +| `make status` | Check service status | +| `make help` | Show all available commands | ## 🔄 Database Reset (Start Fresh if Needed) @@ -128,7 +132,7 @@ If you need to completely reset your database and start fresh: 3. **Restart Services**: ```bash - docker-compose up -d + docker-compose --profile full up -d ``` 4. **Reconfigure**: @@ -144,6 +148,7 @@ The reset script safely removes all tables, functions, triggers, and policies wi Make is required for the development workflow. Installation varies by platform: ### Windows + ```bash # Option 1: Using Chocolatey choco install make @@ -157,12 +162,14 @@ wsl --install ``` ### macOS + ```bash # Make comes pre-installed on macOS # If needed: brew install make ``` ### Linux + ```bash # Debian/Ubuntu sudo apt-get install make @@ -324,7 +331,7 @@ This is useful when: After changing hostname or ports: -1. Restart Docker containers: `docker-compose down && docker-compose up -d` +1. Restart Docker containers: `docker-compose down && docker-compose --profile full up -d` 2. Access the UI at: `http://${HOST}:${ARCHON_UI_PORT}` 3. Update your AI client configuration with the new hostname and MCP port @@ -333,8 +340,8 @@ After changing hostname or ports: ### Quick Commands ```bash -# Start hybrid development environment (recommended) -make dev +# Start hybrid development environment (recommended for development) +make dev-hybrid # View all available commands make help @@ -351,33 +358,39 @@ make clean # Clean up containers and volumes ### Development Modes -#### Hybrid Mode (Recommended) +#### Hybrid Mode (Recommended for development) + Best for active development with instant frontend updates: + ```bash -make dev -# or make dev-hybrid ``` + - Backend services run in Docker with hot reload - Frontend runs locally with HMR (Hot Module Replacement) - Instant UI updates without Docker rebuilds **Security Note**: The frontend dev server uses `--host` flag to allow network access. This is useful for: + - Testing on different devices on your network - Accessing the UI from Docker containers However, this exposes the dev server to your local network. In production or on untrusted networks, ensure proper firewall rules are in place. #### Full Docker Mode + For testing production-like environment: + ```bash make dev-docker ``` + - All services run in Docker -- Slower frontend updates (requires rebuild) #### Manual Service Control + Start individual services: + ```bash make backend # Start backend services only make frontend # Start frontend only @@ -441,7 +454,9 @@ make deep-clean # Also remove dependencies ### Common Issues and Solutions #### Port Conflicts + If you see "Port already in use" errors: + ```bash # Check what's using a port (e.g., 3737) lsof -i :3737 @@ -455,7 +470,9 @@ kill ``` #### Docker Permission Issues (Linux) + If you encounter permission errors with Docker: + ```bash # Add your user to the docker group sudo usermod -aG docker $USER @@ -465,6 +482,7 @@ newgrp docker ``` #### Windows-Specific Issues + - **Make not found**: Install Make via Chocolatey, Scoop, or WSL2 (see [Installing Make](#installing-make)) - **Line ending issues**: Configure Git to use LF endings: ```bash @@ -472,6 +490,7 @@ newgrp docker ``` #### Environment Variables Not Loading + ```bash # Verify .env file exists and has required variables make doctor @@ -482,12 +501,15 @@ grep SUPABASE_SERVICE_KEY .env ``` #### Frontend Can't Connect to Backend + - Check backend is running: `curl http://localhost:8181/health` - Verify port configuration in `.env` - For custom ports, ensure both `ARCHON_SERVER_PORT` and `VITE_ARCHON_SERVER_PORT` are set #### Docker Compose Hangs + If `docker-compose` commands hang: + ```bash # Reset Docker Compose docker-compose down --remove-orphans @@ -497,17 +519,21 @@ docker system prune -f ``` #### Hot Reload Not Working + - **Frontend**: Ensure you're running in hybrid mode (`make dev-hybrid`) for best HMR experience - **Backend**: Check that volumes are mounted correctly in `docker-compose.yml` - **File permissions**: On some systems, mounted volumes may have permission issues #### Check Your Setup + Run the doctor command to validate your environment: + ```bash make doctor ``` This will check: + - Required tools installation - Environment variables - Port availability diff --git a/archon-ui-main/package.json b/archon-ui-main/package.json index 4e88d678be..fc6a1d1a60 100644 --- a/archon-ui-main/package.json +++ b/archon-ui-main/package.json @@ -4,7 +4,7 @@ "private": true, "type": "module", "scripts": { - "dev": "npx vite --port 3737 --host", + "dev": "npx vite", "build": "npx vite build", "lint": "eslint . --ext .js,.jsx,.ts,.tsx", "preview": "npx vite preview", diff --git a/archon-ui-main/src/config/api.ts b/archon-ui-main/src/config/api.ts index 1efc952d2e..9ef568fc1c 100644 --- a/archon-ui-main/src/config/api.ts +++ b/archon-ui-main/src/config/api.ts @@ -20,11 +20,13 @@ export function getApiUrl(): string { // For development, construct from window location const protocol = window.location.protocol; const host = window.location.hostname; - // Try VITE_ prefixed env var first, then fallback to default - const port = import.meta.env.VITE_ARCHON_SERVER_PORT || (() => { - console.info('[Archon] Using default ARCHON_SERVER_PORT: 8181'); - return '8181'; - })(); + // Try VITE_ prefixed env vars first, then fallback to default + const port = import.meta.env.VITE_ARCHON_SERVER_PORT || + import.meta.env.VITE_PORT || + (() => { + console.info('[Archon] Using default ARCHON_SERVER_PORT: 8181'); + return '8181'; + })(); return `${protocol}//${host}:${port}`; } diff --git a/archon-ui-main/vite.config.ts b/archon-ui-main/vite.config.ts index 4a6264b1e9..f6b7563f22 100644 --- a/archon-ui-main/vite.config.ts +++ b/archon-ui-main/vite.config.ts @@ -15,7 +15,7 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => { // Get host and port from environment variables or use defaults // For internal Docker communication, use the service name // For external access, use the HOST from environment - const isDocker = process.env.DOCKER_ENV === 'true' || !!process.env.HOSTNAME; + const isDocker = process.env.DOCKER_ENV === 'true' || existsSync('/.dockerenv'); const internalHost = 'archon-server'; // Docker service name for internal communication const externalHost = process.env.HOST || 'localhost'; // Host for external access const host = isDocker ? internalHost : externalHost; diff --git a/check-env.js b/check-env.js new file mode 100644 index 0000000000..0c5f5e2368 --- /dev/null +++ b/check-env.js @@ -0,0 +1,80 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +// Check if .env file exists +const envPath = path.join(process.cwd(), '.env'); +if (!fs.existsSync(envPath)) { + console.error('ERROR: .env file not found! Create one from .env.example'); + process.exit(1); +} + +// Read and parse .env file +const envContent = fs.readFileSync(envPath, 'utf8'); +const lines = envContent.split('\n'); +const envVars = {}; + +// Parse .env properly, ignoring comments and empty lines +lines.forEach(line => { + const trimmed = line.trim(); + + // Skip empty lines and comments + if (!trimmed || trimmed.startsWith('#')) return; + + // Find the first = sign (values might contain = signs) + const equalIndex = trimmed.indexOf('='); + if (equalIndex === -1) return; + + const key = trimmed.substring(0, equalIndex).trim(); + const value = trimmed.substring(equalIndex + 1).trim(); + + // Remove surrounding quotes if present + const unquotedValue = value.replace(/^["']|["']$/g, ''); + + if (key) { + envVars[key] = unquotedValue; + } +}); + +// Check required variables +const required = ['SUPABASE_URL', 'SUPABASE_SERVICE_KEY']; +const missing = []; +const empty = []; + +required.forEach(varName => { + if (!(varName in envVars)) { + missing.push(varName); + } else if (envVars[varName] === '') { + empty.push(varName); + } +}); + +// Report errors +if (missing.length > 0) { + console.error('ERROR: Missing required env vars: ' + missing.join(', ')); + console.error('Please add these variables to your .env file'); + process.exit(1); +} + +if (empty.length > 0) { + console.error('ERROR: Empty values for env vars: ' + empty.join(', ')); + console.error('Please provide values for these variables in your .env file'); + process.exit(1); +} + +// Validate URL format for SUPABASE_URL +try { + new URL(envVars['SUPABASE_URL']); +} catch (e) { + console.error('ERROR: SUPABASE_URL is not a valid URL: ' + envVars['SUPABASE_URL']); + process.exit(1); +} + +// Basic validation for service key (should be non-trivial) +if (envVars['SUPABASE_SERVICE_KEY'].length < 10) { + console.error('ERROR: SUPABASE_SERVICE_KEY appears to be invalid (too short)'); + process.exit(1); +} + +console.log('Environment OK: SUPABASE_URL and SUPABASE_SERVICE_KEY found and validated.'); \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index bd2d16a73d..0155726e5d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,7 +16,7 @@ services: args: BUILDKIT_INLINE_CACHE: 1 ARCHON_SERVER_PORT: ${ARCHON_SERVER_PORT:-8181} - container_name: Archon-Server + container_name: archon-server ports: - "${ARCHON_SERVER_PORT:-8181}:${ARCHON_SERVER_PORT:-8181}" environment: @@ -71,7 +71,7 @@ services: args: BUILDKIT_INLINE_CACHE: 1 ARCHON_MCP_PORT: ${ARCHON_MCP_PORT:-8051} - container_name: Archon-MCP + container_name: archon-mcp ports: - "${ARCHON_MCP_PORT:-8051}:${ARCHON_MCP_PORT:-8051}" environment: @@ -116,7 +116,7 @@ services: args: BUILDKIT_INLINE_CACHE: 1 ARCHON_AGENTS_PORT: ${ARCHON_AGENTS_PORT:-8052} - container_name: Archon-Agents + container_name: archon-agents ports: - "${ARCHON_AGENTS_PORT:-8052}:${ARCHON_AGENTS_PORT:-8052}" environment: @@ -146,17 +146,18 @@ services: frontend: profiles: ["frontend", "full"] build: ./archon-ui-main - container_name: Archon-UI + container_name: archon-ui ports: - "${ARCHON_UI_PORT:-3737}:3737" environment: - VITE_API_URL=http://${HOST:-localhost}:${ARCHON_SERVER_PORT:-8181} + - VITE_ARCHON_SERVER_PORT=${ARCHON_SERVER_PORT:-8181} - ARCHON_SERVER_PORT=${ARCHON_SERVER_PORT:-8181} - HOST=${HOST:-localhost} networks: - app-network healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:5173"] + test: ["CMD", "curl", "-f", "http://localhost:3737"] interval: 30s timeout: 10s retries: 3 From 80b0f703caf96d3fe2b356e21842bb391a926acc Mon Sep 17 00:00:00 2001 From: Rasmus Widing Date: Fri, 22 Aug 2025 11:53:57 +0300 Subject: [PATCH 08/15] Fix container name resolution for MCP server - Add dynamic container name resolution with three-tier strategy - Support environment variables for custom container names - Add service discovery labels to docker-compose services - Update BackendStartupError with correct container name references --- .env.example | 7 ++ README.md | 2 +- .../src/components/BackendStartupError.tsx | 4 +- docker-compose.yml | 20 ++++-- python/src/server/api_routes/mcp_api.py | 66 ++++++++++++++++--- 5 files changed, 84 insertions(+), 15 deletions(-) diff --git a/.env.example b/.env.example index ca14233df3..2a31f525c6 100644 --- a/.env.example +++ b/.env.example @@ -36,6 +36,13 @@ ARCHON_AGENTS_PORT=8052 ARCHON_UI_PORT=3737 ARCHON_DOCS_PORT=3838 +# Container names (optional - defaults shown) +# Customize these if you need different container names for your deployment +# ARCHON_SERVER_CONTAINER_NAME=archon-server +# ARCHON_MCP_CONTAINER_NAME=archon-mcp +# ARCHON_AGENTS_CONTAINER_NAME=archon-agents +# ARCHON_UI_CONTAINER_NAME=archon-ui + # Frontend-specific port configuration (optional) # VITE_ARCHON_SERVER_PORT - Override the API server port for frontend only # This is useful when the frontend needs to connect to a different port than ARCHON_SERVER_PORT diff --git a/README.md b/README.md index 40a754fdf1..d58416ada5 100644 --- a/README.md +++ b/README.md @@ -360,7 +360,7 @@ make clean # Clean up containers and volumes #### Hybrid Mode (Recommended for development) -Best for active development with instant frontend updates: +Best for active development with instant local frontend updates: ```bash make dev-hybrid diff --git a/archon-ui-main/src/components/BackendStartupError.tsx b/archon-ui-main/src/components/BackendStartupError.tsx index a7a1e78241..8d6447eae2 100644 --- a/archon-ui-main/src/components/BackendStartupError.tsx +++ b/archon-ui-main/src/components/BackendStartupError.tsx @@ -28,12 +28,12 @@ export const BackendStartupError: React.FC = () => { Check Docker Logs

- Check the Archon-Server logs in Docker Desktop for detailed error information. + Check the Archon API server container logs in Docker Desktop for detailed error information.

1. Open Docker Desktop

2. Go to Containers tab

-

3. Click on Archon-Server

+

3. Look for the Archon server container (typically named archon-server or similar)

4. View the logs for the specific error message

diff --git a/docker-compose.yml b/docker-compose.yml index 0155726e5d..a32bc0f130 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,7 +16,10 @@ services: args: BUILDKIT_INLINE_CACHE: 1 ARCHON_SERVER_PORT: ${ARCHON_SERVER_PORT:-8181} - container_name: archon-server + container_name: ${ARCHON_SERVER_CONTAINER_NAME:-archon-server} + labels: + - "archon.service=server" + - "archon.type=api" ports: - "${ARCHON_SERVER_PORT:-8181}:${ARCHON_SERVER_PORT:-8181}" environment: @@ -71,7 +74,10 @@ services: args: BUILDKIT_INLINE_CACHE: 1 ARCHON_MCP_PORT: ${ARCHON_MCP_PORT:-8051} - container_name: archon-mcp + container_name: ${ARCHON_MCP_CONTAINER_NAME:-archon-mcp} + labels: + - "archon.service=mcp" + - "archon.type=protocol" ports: - "${ARCHON_MCP_PORT:-8051}:${ARCHON_MCP_PORT:-8051}" environment: @@ -116,7 +122,10 @@ services: args: BUILDKIT_INLINE_CACHE: 1 ARCHON_AGENTS_PORT: ${ARCHON_AGENTS_PORT:-8052} - container_name: archon-agents + container_name: ${ARCHON_AGENTS_CONTAINER_NAME:-archon-agents} + labels: + - "archon.service=agents" + - "archon.type=ai" ports: - "${ARCHON_AGENTS_PORT:-8052}:${ARCHON_AGENTS_PORT:-8052}" environment: @@ -146,7 +155,10 @@ services: frontend: profiles: ["frontend", "full"] build: ./archon-ui-main - container_name: archon-ui + container_name: ${ARCHON_UI_CONTAINER_NAME:-archon-ui} + labels: + - "archon.service=ui" + - "archon.type=frontend" ports: - "${ARCHON_UI_PORT:-3737}:3737" environment: diff --git a/python/src/server/api_routes/mcp_api.py b/python/src/server/api_routes/mcp_api.py index 84021d6dec..066819ac30 100644 --- a/python/src/server/api_routes/mcp_api.py +++ b/python/src/server/api_routes/mcp_api.py @@ -49,7 +49,7 @@ class MCPServerManager: """Manages the MCP Docker container lifecycle.""" def __init__(self): - self.container_name = "Archon-MCP" # Container name from docker-compose.yml + self.container_name = None # Will be resolved dynamically self.docker_client = None self.container = None self.status: str = "stopped" @@ -62,16 +62,59 @@ def __init__(self): self._min_operation_interval = 2.0 # Minimum 2 seconds between operations self._initialize_docker_client() + def _resolve_container(self): + """Dynamically resolve the MCP container using multiple strategies.""" + if not self.docker_client: + return None + + import os + + # Strategy 1: Try environment variable + env_name = os.getenv("ARCHON_MCP_CONTAINER_NAME") + if env_name: + try: + container = self.docker_client.containers.get(env_name) + self.container_name = env_name + mcp_logger.info(f"Found MCP container via env var: {env_name}") + return container + except NotFound: + mcp_logger.warning(f"Container specified in env var not found: {env_name}") + + # Strategy 2: Try finding by label + try: + containers = self.docker_client.containers.list( + all=True, + filters={"label": "archon.service=mcp"} + ) + if containers: + container = containers[0] + self.container_name = container.name + mcp_logger.info(f"Found MCP container via label: {self.container_name}") + return container + except Exception as e: + mcp_logger.debug(f"Label search failed: {e}") + + # Strategy 3: Try known container names (backward compatibility) + fallback_names = ["archon-mcp", "Archon-MCP"] + for name in fallback_names: + try: + container = self.docker_client.containers.get(name) + self.container_name = name + mcp_logger.info(f"Found MCP container via fallback name: {name}") + return container + except NotFound: + continue + + mcp_logger.warning("Could not find MCP container using any strategy") + return None + def _initialize_docker_client(self): """Initialize Docker client and get container reference.""" try: self.docker_client = docker.from_env() - try: - self.container = self.docker_client.containers.get(self.container_name) - mcp_logger.info(f"Found Docker container: {self.container_name}") - except NotFound: - mcp_logger.warning(f"Docker container {self.container_name} not found") - self.container = None + self.container = self._resolve_container() + if not self.container: + mcp_logger.warning("MCP container not found during initialization") except Exception as e: mcp_logger.error(f"Failed to initialize Docker client: {str(e)}") self.docker_client = None @@ -85,10 +128,17 @@ def _get_container_status(self) -> str: if self.container: self.container.reload() # Refresh container info else: - self.container = self.docker_client.containers.get(self.container_name) + # Try to resolve container again if we don't have it + self.container = self._resolve_container() + if not self.container: + return "not_found" return self.container.status except NotFound: + # Try to resolve again in case container was recreated + self.container = self._resolve_container() + if self.container: + return self.container.status return "not_found" except Exception as e: mcp_logger.error(f"Error getting container status: {str(e)}") From edaf1295b8c72f4f3c1690527b3d7f38dc952ec0 Mon Sep 17 00:00:00 2001 From: Rasmus Widing Date: Fri, 22 Aug 2025 12:04:05 +0300 Subject: [PATCH 09/15] Fix frontend test failures in API configuration tests - Update environment variable names to use VITE_ prefix that matches production code - Fix MCP client service tests to use singleton instance export - Update default behavior tests to expect fallback to port 8181 - All 77 frontend tests now pass --- archon-ui-main/test/config/api.test.ts | 42 +++++++++++++++----------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/archon-ui-main/test/config/api.test.ts b/archon-ui-main/test/config/api.test.ts index ac06c78ef3..bbf58f5b92 100644 --- a/archon-ui-main/test/config/api.test.ts +++ b/archon-ui-main/test/config/api.test.ts @@ -41,23 +41,33 @@ describe('API Configuration', () => { expect(getApiUrl()).toBe(''); }); - it('should throw error when ARCHON_SERVER_PORT is not set in development', async () => { - // Development mode without port + it('should use default port 8181 when no port environment variables are set in development', async () => { + // Development mode without any port variables delete (import.meta.env as any).PROD; delete (import.meta.env as any).VITE_API_URL; + delete (import.meta.env as any).VITE_ARCHON_SERVER_PORT; + delete (import.meta.env as any).VITE_PORT; delete (import.meta.env as any).ARCHON_SERVER_PORT; + // Mock window.location + Object.defineProperty(window, 'location', { + value: { + protocol: 'http:', + hostname: 'localhost' + }, + writable: true + }); + const { getApiUrl } = await import('../../src/config/api'); - expect(() => getApiUrl()).toThrow('ARCHON_SERVER_PORT environment variable is required'); - expect(() => getApiUrl()).toThrow('Default value: 8181'); + expect(getApiUrl()).toBe('http://localhost:8181'); }); - it('should use ARCHON_SERVER_PORT when set in development', async () => { - // Development mode with custom port + it('should use VITE_ARCHON_SERVER_PORT when set in development', async () => { + // Development mode with custom port via VITE_ prefix delete (import.meta.env as any).PROD; delete (import.meta.env as any).VITE_API_URL; - (import.meta.env as any).ARCHON_SERVER_PORT = '9191'; + (import.meta.env as any).VITE_ARCHON_SERVER_PORT = '9191'; // Mock window.location Object.defineProperty(window, 'location', { @@ -73,10 +83,10 @@ describe('API Configuration', () => { }); it('should use custom port with https protocol', async () => { - // Development mode with custom port and https + // Development mode with custom port and https via VITE_ prefix delete (import.meta.env as any).PROD; delete (import.meta.env as any).VITE_API_URL; - (import.meta.env as any).ARCHON_SERVER_PORT = '8443'; + (import.meta.env as any).VITE_ARCHON_SERVER_PORT = '8443'; // Mock window.location with https Object.defineProperty(window, 'location', { @@ -139,7 +149,7 @@ describe('API Configuration', () => { vi.resetModules(); delete (import.meta.env as any).PROD; delete (import.meta.env as any).VITE_API_URL; - (import.meta.env as any).ARCHON_SERVER_PORT = port; + (import.meta.env as any).VITE_ARCHON_SERVER_PORT = port; Object.defineProperty(window, 'location', { value: { @@ -174,11 +184,10 @@ describe('MCP Client Service Configuration', () => { it('should throw error when ARCHON_MCP_PORT is not set', async () => { delete (import.meta.env as any).ARCHON_MCP_PORT; - const { MCPClientService } = await import('../../src/services/mcpClientService'); - const service = new MCPClientService(); + const { mcpClientService } = await import('../../src/services/mcpClientService'); - await expect(service.createArchonClient()).rejects.toThrow('ARCHON_MCP_PORT environment variable is required'); - await expect(service.createArchonClient()).rejects.toThrow('Default value: 8051'); + await expect(mcpClientService.createArchonClient()).rejects.toThrow('ARCHON_MCP_PORT environment variable is required'); + await expect(mcpClientService.createArchonClient()).rejects.toThrow('Default value: 8051'); }); it('should use ARCHON_MCP_PORT when set', async () => { @@ -205,11 +214,10 @@ describe('MCP Client Service Configuration', () => { }) }); - const { MCPClientService } = await import('../../src/services/mcpClientService'); - const service = new MCPClientService(); + const { mcpClientService } = await import('../../src/services/mcpClientService'); try { - await service.createArchonClient(); + await mcpClientService.createArchonClient(); // Verify the fetch was called with the correct URL expect(global.fetch).toHaveBeenCalledWith( From 30a26a4dc059402d5bb3fac5139f5e500ba3f550 Mon Sep 17 00:00:00 2001 From: Rasmus Widing Date: Fri, 22 Aug 2025 12:20:11 +0300 Subject: [PATCH 10/15] Fix make stop-local to avoid Docker daemon interference Replace aggressive kill -9 with targeted process termination: - Filter processes by command name (node/vite/python/uvicorn) before killing - Use graceful SIGTERM instead of SIGKILL - Add process verification to avoid killing Docker-related processes - Improve logging with descriptive step messages --- Makefile | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index fe9bbb851b..921cde0858 100644 --- a/Makefile +++ b/Makefile @@ -128,10 +128,18 @@ dev-local: check-env install # Stop local services stop-local: @echo "Stopping local services..." + @echo "Stopping Python API server..." @pkill -f "python -m src.server.main" || true + @echo "Stopping Vite dev server..." @pkill -f "vite" || true - @lsof -ti:3737 | xargs kill -9 2>/dev/null || true - @lsof -ti:8181 | xargs kill -9 2>/dev/null || true + @echo "Gracefully stopping any remaining processes on local ports..." + @# First try graceful shutdown, then force kill only specific processes + @lsof -ti:3737 2>/dev/null | while read pid; do \ + ps -p $$pid -o comm= 2>/dev/null | grep -E "(node|vite)" >/dev/null && kill $$pid 2>/dev/null || true; \ + done || true + @lsof -ti:8181 2>/dev/null | while read pid; do \ + ps -p $$pid -o comm= 2>/dev/null | grep -E "(python|uvicorn)" >/dev/null && kill $$pid 2>/dev/null || true; \ + done || true @echo "Local services stopped" # Production environment From 893f57349ae9b18c7ae6a90c0a9ce99b020e8c5c Mon Sep 17 00:00:00 2001 From: Rasmus Widing Date: Fri, 22 Aug 2025 13:31:49 +0300 Subject: [PATCH 11/15] refactor: Simplify development workflow based on comprehensive review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Reduced Makefile from 344 lines (43 targets) to 83 lines (8 essential targets) - Removed unnecessary environment variables (*_CONTAINER_NAME variables) - Fixed Windows compatibility by removing Unix-specific commands - Added security fixes to check-env.js (path validation) - Simplified MCP container discovery to use fixed container names - Fixed 'make stop' to properly handle Docker Compose profiles - Updated documentation to reflect simplified workflow - Restored original .env.example with comprehensive Supabase key documentation This addresses all critical issues from code review: - Cross-platform compatibility ✅ - Security vulnerabilities fixed ✅ - 81% reduction in complexity ✅ - Maintains all essential functionality ✅ All tests pass: Frontend (77/77), Backend (267/267) --- .env.example | 13 - Makefile | 388 ++++-------------------- README.md | 140 +++------ archon-ui-main/src/config/api.ts | 13 +- check-env.js | 75 +++-- docker-compose.yml | 20 +- python/src/server/api_routes/mcp_api.py | 52 +--- 7 files changed, 158 insertions(+), 543 deletions(-) diff --git a/.env.example b/.env.example index 2a31f525c6..195ab112b3 100644 --- a/.env.example +++ b/.env.example @@ -36,19 +36,6 @@ ARCHON_AGENTS_PORT=8052 ARCHON_UI_PORT=3737 ARCHON_DOCS_PORT=3838 -# Container names (optional - defaults shown) -# Customize these if you need different container names for your deployment -# ARCHON_SERVER_CONTAINER_NAME=archon-server -# ARCHON_MCP_CONTAINER_NAME=archon-mcp -# ARCHON_AGENTS_CONTAINER_NAME=archon-agents -# ARCHON_UI_CONTAINER_NAME=archon-ui - -# Frontend-specific port configuration (optional) -# VITE_ARCHON_SERVER_PORT - Override the API server port for frontend only -# This is useful when the frontend needs to connect to a different port than ARCHON_SERVER_PORT -# If not set, frontend will use VITE_PORT (if available) or default to 8181 -# VITE_ARCHON_SERVER_PORT=8181 - # Embedding Configuration # Dimensions for embedding vectors (1536 for OpenAI text-embedding-3-small) EMBEDDING_DIMENSIONS=1536 diff --git a/Makefile b/Makefile index 921cde0858..5459cb34ac 100644 --- a/Makefile +++ b/Makefile @@ -1,353 +1,83 @@ -# Archon Development Makefile -# Cross-platform development environment management - -# Shell flags for better error handling +# Archon Makefile - Simple, Secure, Cross-Platform SHELL := /bin/bash .SHELLFLAGS := -ec -.PHONY: help dev dev-hybrid dev-docker dev-local prod backend frontend \ - build test test-frontend test-backend test-coverage clean clean-confirm \ - deep-clean deep-clean-confirm stop stop-local stop-prod logs status install \ - install-backend install-frontend check-env check-frontend-deps doctor health \ - lint lint-frontend lint-backend typecheck format pre-commit restart \ - watch-backend watch-mcp watch-agents shell-backend shell-mcp migrate backup-db \ - logs-archon-server logs-archon-mcp logs-archon-agents logs-archon-ui +.PHONY: help dev dev-docker stop test lint clean install check -# Default target - show help help: - @echo "Archon Development Environment" - @echo "==============================" - @echo "" - @echo "Quick Start:" - @echo " make install - Install all dependencies" - @echo " make dev - Start hybrid dev environment (backend in Docker, frontend local)" - @echo " make prod - Start production environment (all in Docker)" - @echo "" - @echo "Development Modes:" - @echo " make dev-hybrid - Backend in Docker, frontend locally with HMR (default)" - @echo " make dev-docker - Everything in Docker (slower frontend updates)" - @echo " make dev-local - API server and frontend locally (MCP/Agents stay in Docker)" - @echo "" - @echo "Management:" - @echo " make stop - Stop all Docker containers" - @echo " make stop-local - Stop all local services" - @echo " make clean - Stop and remove all containers and volumes" - @echo " make logs - Show logs from all services" - @echo " make status - Show status of all services" - @echo "" - @echo "Testing:" - @echo " make test - Run all tests (frontend and backend)" - @echo " make test-frontend - Run frontend tests only" - @echo " make test-backend - Run backend tests only" - @echo "" - @echo "Utilities:" - @echo " make doctor - Check development environment setup" - @echo "" - @echo "Individual Services:" - @echo " make frontend - Start frontend only (local)" - @echo " make backend - Start backend services only (Docker)" - @echo "" - -# Install all dependencies + @echo "Archon Development Commands" + @echo "===========================" + @echo " make dev - Backend in Docker, frontend local (recommended)" + @echo " make dev-docker - Everything in Docker" + @echo " make stop - Stop all services" + @echo " make test - Run tests" + @echo " make lint - Run linters" + @echo " make clean - Remove containers and volumes" + @echo " make install - Install dependencies" + @echo " make check - Check environment setup" + +# Install dependencies install: @echo "Installing dependencies..." @cd archon-ui-main && npm install @cd python && uv sync - @echo "Dependencies installed successfully!" - -# Check and install frontend dependencies if needed -check-frontend-deps: - @cd archon-ui-main && npm install --silent + @echo "✓ Dependencies installed" -# Verify required env vars exist - using Node.js for cross-platform compatibility -check-env: +# Check environment +check: + @echo "Checking environment..." @node check-env.js - -# Default dev target - hybrid mode -dev: dev-hybrid - -# Hybrid development - backend in Docker, frontend local -dev-hybrid: stop-prod check-env check-frontend-deps - @echo "Starting hybrid development environment..." - @echo "Backend services in Docker, Frontend running locally" - @LOG_LEVEL=DEBUG docker-compose --profile backend up -d --build - @echo "" - @echo "=====================================================" - @echo "Development Environment Ready!" - @echo "=====================================================" - @echo "" - @echo "Backend Services in Docker:" - @echo " API Server: http://localhost:$${ARCHON_SERVER_PORT:-8181}" - @echo " MCP Server: http://localhost:$${ARCHON_MCP_PORT:-8051}" - @echo " Agents Service: http://localhost:$${ARCHON_AGENTS_PORT:-8052}" - @echo "" - @echo "Starting frontend server..." - @echo "" - @echo "Commands (in another terminal):" - @echo " make logs - View all logs" - @echo " make stop - Stop everything" - @echo " make status - Check service status" - @echo "" + @echo "Checking Docker..." + @docker --version > /dev/null 2>&1 && echo "✓ Docker installed" || echo "✗ Docker not found" + @docker-compose --version > /dev/null 2>&1 && echo "✓ Docker Compose installed" || echo "✗ Docker Compose not found" + +# Hybrid development (recommended) +dev: check + @echo "Starting hybrid development..." + @echo "Backend: Docker | Frontend: Local with hot reload" + @docker-compose --profile backend up -d --build + @echo "Backend running at http://localhost:8181" + @echo "Starting frontend..." @cd archon-ui-main && npm run dev # Full Docker development -dev-docker: - @echo "Starting full Docker development environment..." - docker-compose --profile full up -d --build - @echo "All services running in Docker" - @echo "UI available at: http://localhost:3737" - -# Full local development - API server and frontend only (MCP/Agents run in Docker) -dev-local: check-env install - @echo "Starting local development environment..." - @echo "API Server and Frontend running locally" - @echo "Note: MCP Server and Agents Service should run in Docker if needed" - @echo "" - @echo "======================================================" - @echo "Local Development Environment" - @echo "======================================================" - @echo "" - @echo "Starting API Server on port 8181..." - @mkdir -p logs - @cd python && uv run python -m src.server.main > ../logs/api-server.log 2>&1 & - @sleep 3 - @echo "" - @echo "Backend service started!" - @echo "" - @echo "API Server: http://localhost:8181" - @echo "" - @echo "Log file: ./logs/api-server.log" - @echo "" - @echo "Starting frontend on port 3737..." - @echo "" - @echo "To run MCP/Agents in Docker, use:" - @echo " docker-compose --profile backend up -d archon-mcp archon-agents" - @echo "" - @cd archon-ui-main && npm run dev - -# Stop local services -stop-local: - @echo "Stopping local services..." - @echo "Stopping Python API server..." - @pkill -f "python -m src.server.main" || true - @echo "Stopping Vite dev server..." - @pkill -f "vite" || true - @echo "Gracefully stopping any remaining processes on local ports..." - @# First try graceful shutdown, then force kill only specific processes - @lsof -ti:3737 2>/dev/null | while read pid; do \ - ps -p $$pid -o comm= 2>/dev/null | grep -E "(node|vite)" >/dev/null && kill $$pid 2>/dev/null || true; \ - done || true - @lsof -ti:8181 2>/dev/null | while read pid; do \ - ps -p $$pid -o comm= 2>/dev/null | grep -E "(python|uvicorn)" >/dev/null && kill $$pid 2>/dev/null || true; \ - done || true - @echo "Local services stopped" - -# Production environment -prod: - @echo "Starting production environment..." - docker-compose --profile full up -d --build - @echo "Production environment started" - @echo "UI available at: http://localhost:3737" - -# Start backend services only -backend: - @echo "Starting backend services in Docker..." - docker-compose --profile backend up -d --build - -# Start frontend only (foreground) -frontend: - @cd archon-ui-main && npm run dev - -# Stop production containers if running -stop-prod: - @echo "Checking for running production containers..." - @docker-compose down 2>/dev/null || true - @echo "Containers stopped" - -# Build all Docker images -build: - @echo "Building all Docker images..." - docker-compose --profile full build +dev-docker: check + @echo "Starting full Docker environment..." + @docker-compose --profile full up -d --build + @echo "✓ All services running" + @echo "Frontend: http://localhost:3737" + @echo "API: http://localhost:8181" -# Run all tests -test: test-frontend test-backend +# Stop all services +stop: + @echo "Stopping all services..." + @docker-compose --profile backend --profile frontend --profile full down + @echo "✓ Services stopped" -# Run frontend tests -test-frontend: +# Run tests +test: @echo "Running frontend tests..." - @cd archon-ui-main && npm run test - -# Run backend tests -test-backend: + @cd archon-ui-main && npm test @echo "Running backend tests..." @cd python && uv run pytest -# Run frontend tests with coverage -test-coverage: - @echo "Running frontend tests with coverage..." - @cd archon-ui-main && npm run test:coverage - -# Stop all containers -stop: - @echo "Stopping all containers..." - @docker-compose --profile backend --profile frontend --profile full down || true - @echo "All services stopped" - -# Clean everything (containers, volumes, node_modules) -clean: - @echo "" - @echo "=========================================" - @echo "⚠️ WARNING: DESTRUCTIVE OPERATION" - @echo "=========================================" - @echo "" - @echo "This command will PERMANENTLY DELETE:" - @echo " • All Docker containers" - @echo " • All Docker volumes (including database data)" - @echo " • All stored documents and embeddings" - @echo " • Docker build cache" - @echo "" - @echo "To proceed, run: make clean-confirm" - @echo "To cancel, press Ctrl+C or do nothing" - @echo "" - -# Actual clean operation (requires explicit confirmation) -clean-confirm: stop - @echo "Cleaning up everything..." - -@docker-compose down -v --remove-orphans - @docker system prune -f - @echo "Cleanup complete" - -# Deep clean including dependencies -deep-clean: - @echo "" - @echo "=========================================" - @echo "⚠️ WARNING: COMPLETE RESET" - @echo "=========================================" - @echo "" - @echo "This command will PERMANENTLY DELETE:" - @echo " • Everything from 'make clean'" - @echo " • All npm dependencies (node_modules)" - @echo " • Python virtual environment" - @echo "" - @echo "You will need to run 'make install' after this." - @echo "" - @echo "To proceed, run: make deep-clean-confirm" - @echo "" - -# Actual deep clean operation -deep-clean-confirm: clean-confirm - @echo "Performing deep clean..." - @echo "Please manually delete archon-ui-main/node_modules and python/.venv if needed" - @echo "Deep clean complete. Run 'make install' to reinstall dependencies." - -# Show logs from all services -logs: - @docker-compose logs -f - -# Show logs from specific service -logs-%: - @docker-compose logs -f $* - -# Show status of all services -status: - @echo "Service Status:" - @echo "===============" - -@docker-compose ps - @echo "" - @echo "Check http://localhost:3737 for frontend status" - -# Restart all services -restart: stop dev - -# Lint frontend code -lint-frontend: +# Run linters +lint: + @echo "Linting frontend..." @cd archon-ui-main && npm run lint + @echo "Linting backend..." + @cd python && uv run ruff check --fix -# Lint backend code -lint-backend: - @cd python && uv run ruff check - -# Lint all code (frontend and backend) -lint: lint-frontend lint-backend - -# Type check backend code -typecheck: - @cd python && uv run mypy src/ - -# Format code -format: - @cd python && uv run ruff format - @cd archon-ui-main && npx prettier --write "src/**/*.{ts,tsx,js,jsx}" - -# Run pre-commit checks -pre-commit: lint-frontend lint-backend typecheck test - @echo "All pre-commit checks passed!" - -# Docker health check -health: - @echo "Checking service health..." - @echo "API Server: http://localhost:8181/health" - @echo "MCP Server: http://localhost:8051/health" - @echo "Agents Service: http://localhost:8052/health" - @echo "Frontend: http://localhost:3737" - -# Watch backend logs -watch-backend: - @docker-compose logs -f archon-server - -# Watch MCP logs -watch-mcp: - @docker-compose logs -f archon-mcp - -# Watch agents logs -watch-agents: - @docker-compose logs -f archon-agents - -# Open shell in backend container -shell-backend: - @docker-compose exec archon-server /bin/sh - -# Open shell in MCP container -shell-mcp: - @docker-compose exec archon-mcp /bin/sh - -# Run database migrations -migrate: - @echo "Running database migrations..." - @cd python && uv run python -m src.server.db.migrate - -# Backup database -backup-db: - @echo "Creating database backup..." - @docker-compose exec archon-server python -m src.server.db.backup - -# Development environment validation -doctor: - @echo "🔍 Checking development environment..." - @echo "" - @echo "=== Required Tools ===" - @command -v docker >/dev/null 2>&1 && echo "✅ Docker: $$(docker --version | cut -d' ' -f3)" || echo "❌ Docker: Not installed" - @command -v docker-compose >/dev/null 2>&1 && echo "✅ Docker Compose: $$(docker-compose --version | cut -d' ' -f4)" || echo "❌ Docker Compose: Not installed" - @command -v node >/dev/null 2>&1 && echo "✅ Node.js: $$(node --version)" || echo "❌ Node.js: Not installed" - @command -v npm >/dev/null 2>&1 && echo "✅ npm: $$(npm --version)" || echo "❌ npm: Not installed" - @command -v python3 >/dev/null 2>&1 && echo "✅ Python: $$(python3 --version | cut -d' ' -f2)" || echo "❌ Python: Not installed" - @command -v uv >/dev/null 2>&1 && echo "✅ uv: $$(uv --version | cut -d' ' -f2)" || echo "❌ uv: Not installed (needed for local development)" - @command -v make >/dev/null 2>&1 && echo "✅ Make: $$(make --version | head -1 | cut -d' ' -f3)" || echo "❌ Make: Not installed" - @echo "" - @echo "=== Environment Variables ===" - @test -f .env && echo "✅ .env file exists" || echo "❌ .env file missing (copy from .env.example)" - @test -f .env && grep -q "SUPABASE_URL=" .env && echo "✅ SUPABASE_URL is set" || echo "❌ SUPABASE_URL not set" - @test -f .env && grep -q "SUPABASE_SERVICE_KEY=" .env && echo "✅ SUPABASE_SERVICE_KEY is set" || echo "❌ SUPABASE_SERVICE_KEY not set" - @echo "" - @echo "=== Port Availability ===" - @lsof -i :8181 >/dev/null 2>&1 && echo "⚠️ Port 8181 (API Server) is in use" || echo "✅ Port 8181 (API Server) is available" - @lsof -i :8051 >/dev/null 2>&1 && echo "⚠️ Port 8051 (MCP Server) is in use" || echo "✅ Port 8051 (MCP Server) is available" - @lsof -i :8052 >/dev/null 2>&1 && echo "⚠️ Port 8052 (Agents) is in use" || echo "✅ Port 8052 (Agents) is available" - @lsof -i :3737 >/dev/null 2>&1 && echo "⚠️ Port 3737 (Frontend) is in use" || echo "✅ Port 3737 (Frontend) is available" - @echo "" - @echo "=== Docker Status ===" - @docker info >/dev/null 2>&1 && echo "✅ Docker daemon is running" || echo "❌ Docker daemon is not running" - @echo "" - @echo "🏁 Environment check complete!" +# Clean everything (with confirmation) +clean: + @echo "⚠️ This will remove all containers and volumes" + @read -p "Are you sure? (y/N) " -n 1 -r; \ + echo; \ + if [[ $$REPLY =~ ^[Yy]$$ ]]; then \ + docker-compose down -v --remove-orphans; \ + echo "✓ Cleaned"; \ + else \ + echo "Cancelled"; \ + fi .DEFAULT_GOAL := help \ No newline at end of file diff --git a/README.md b/README.md index d58416ada5..132030fc68 100644 --- a/README.md +++ b/README.md @@ -105,16 +105,16 @@ This new vision for Archon replaces the old one (the agenteer). Archon used to b ### 🚀 Quick Command Reference -| Command | Description | -| -------------- | ---------------------------------------------------------------- | -| `make dev` | Start hybrid dev environment (backend in Docker, frontend local) | -| `make prod` | Start production environment (all in Docker) | -| `make install` | Install all dependencies | -| `make test` | Run all tests | -| `make stop` | Stop all services | -| `make logs` | View service logs | -| `make status` | Check service status | -| `make help` | Show all available commands | +| Command | Description | +| ---------------- | ---------------------------------------------------------- | +| `make dev` | Start hybrid dev (backend in Docker, frontend local) ⭐ | +| `make dev-docker`| Everything in Docker | +| `make stop` | Stop all services | +| `make test` | Run all tests | +| `make lint` | Run linters | +| `make install` | Install dependencies | +| `make check` | Check environment setup | +| `make clean` | Remove containers and volumes (with confirmation) | ## 🔄 Database Reset (Start Fresh if Needed) @@ -337,114 +337,62 @@ After changing hostname or ports: ## 🔧 Development -### Quick Commands +### Quick Start ```bash -# Start hybrid development environment (recommended for development) -make dev-hybrid - -# View all available commands -make help - -# Common development commands -make install # Install all dependencies -make test # Run all tests -make lint-frontend # Lint frontend code -make lint-backend # Lint backend code -make logs # View service logs -make stop # Stop all services -make clean # Clean up containers and volumes -``` - -### Development Modes +# Install dependencies +make install -#### Hybrid Mode (Recommended for development) +# Start development (recommended) +make dev # Backend in Docker, frontend local with hot reload -Best for active development with instant local frontend updates: +# Alternative: Everything in Docker +make dev-docker # All services in Docker -```bash -make dev-hybrid +# Stop everything +make stop ``` -- Backend services run in Docker with hot reload -- Frontend runs locally with HMR (Hot Module Replacement) -- Instant UI updates without Docker rebuilds - -**Security Note**: The frontend dev server uses `--host` flag to allow network access. This is useful for: +### Development Modes -- Testing on different devices on your network -- Accessing the UI from Docker containers +#### Hybrid Mode (Recommended) - `make dev` -However, this exposes the dev server to your local network. In production or on untrusted networks, ensure proper firewall rules are in place. +Best for active development with instant frontend updates: +- Backend services run in Docker (isolated, consistent) +- Frontend runs locally with hot module replacement +- Instant UI updates without Docker rebuilds -#### Full Docker Mode +#### Full Docker Mode - `make dev-docker` For testing production-like environment: +- All services run in Docker containers +- Better for integration testing +- Slower frontend updates -```bash -make dev-docker -``` - -- All services run in Docker - -#### Manual Service Control - -Start individual services: +### Testing & Code Quality ```bash -make backend # Start backend services only -make frontend # Start frontend only -``` +# Run tests +make test # Run all tests -### Testing - -```bash -# Run all tests -make test +# Run linters +make lint # Lint all code -# Frontend tests -make test-frontend -cd archon-ui-main && npm run test:coverage +# Check environment +make check # Verify environment setup -# Backend tests -make test-backend -# (Optional) run directly via uv -cd python && uv run pytest +# Clean up +make clean # Remove containers and volumes (asks for confirmation) ``` -### Code Quality +### Viewing Logs ```bash -# Run all checks -make pre-commit - -# Individual checks -make lint-frontend -make lint-backend -make typecheck -``` - -### Service Management - -```bash -# View service status -make status - -# View logs -make logs # All services -make watch-backend # Watch backend logs -make watch-mcp # Watch MCP logs -make watch-agents # Watch agents logs - -# Health check -make health - -# Restart services -make restart - -# Clean everything -make clean # Remove containers -make deep-clean # Also remove dependencies +# View logs using Docker Compose directly +docker-compose logs -f # All services +docker-compose logs -f archon-server # API server +docker-compose logs -f archon-mcp # MCP server +docker-compose logs -f archon-ui # Frontend ``` **Note**: The backend services are configured with `--reload` flag in their uvicorn commands and have source code mounted as volumes for automatic hot reloading when you make changes. diff --git a/archon-ui-main/src/config/api.ts b/archon-ui-main/src/config/api.ts index 9ef568fc1c..ec3eb2510c 100644 --- a/archon-ui-main/src/config/api.ts +++ b/archon-ui-main/src/config/api.ts @@ -20,13 +20,12 @@ export function getApiUrl(): string { // For development, construct from window location const protocol = window.location.protocol; const host = window.location.hostname; - // Try VITE_ prefixed env vars first, then fallback to default - const port = import.meta.env.VITE_ARCHON_SERVER_PORT || - import.meta.env.VITE_PORT || - (() => { - console.info('[Archon] Using default ARCHON_SERVER_PORT: 8181'); - return '8181'; - })(); + // Use configured port or default to 8181 + const port = import.meta.env.VITE_ARCHON_SERVER_PORT || '8181'; + + if (!import.meta.env.VITE_ARCHON_SERVER_PORT) { + console.info('[Archon] Using default ARCHON_SERVER_PORT: 8181'); + } return `${protocol}//${host}:${port}`; } diff --git a/check-env.js b/check-env.js index 0c5f5e2368..938084db27 100644 --- a/check-env.js +++ b/check-env.js @@ -3,78 +3,71 @@ const fs = require('fs'); const path = require('path'); -// Check if .env file exists -const envPath = path.join(process.cwd(), '.env'); +// Secure path resolution +const projectRoot = process.cwd(); +const envPath = path.resolve(projectRoot, '.env'); + +// Security: Validate path is within project +if (!envPath.startsWith(projectRoot)) { + console.error('Security error: Invalid .env path'); + process.exit(1); +} + +// Check if .env exists if (!fs.existsSync(envPath)) { - console.error('ERROR: .env file not found! Create one from .env.example'); + console.error('ERROR: .env file not found!'); + console.error('Copy .env.example to .env and add your credentials:'); + console.error(' cp .env.example .env'); process.exit(1); } -// Read and parse .env file +// Parse .env file const envContent = fs.readFileSync(envPath, 'utf8'); -const lines = envContent.split('\n'); const envVars = {}; -// Parse .env properly, ignoring comments and empty lines -lines.forEach(line => { +envContent.split('\n').forEach(line => { const trimmed = line.trim(); - - // Skip empty lines and comments if (!trimmed || trimmed.startsWith('#')) return; - // Find the first = sign (values might contain = signs) - const equalIndex = trimmed.indexOf('='); - if (equalIndex === -1) return; - - const key = trimmed.substring(0, equalIndex).trim(); - const value = trimmed.substring(equalIndex + 1).trim(); - - // Remove surrounding quotes if present - const unquotedValue = value.replace(/^["']|["']$/g, ''); - + const [key, ...valueParts] = trimmed.split('='); if (key) { - envVars[key] = unquotedValue; + const value = valueParts.join('=').trim().replace(/^["']|["']$/g, ''); + envVars[key.trim()] = value; } }); -// Check required variables +// Only check ESSENTIAL variables const required = ['SUPABASE_URL', 'SUPABASE_SERVICE_KEY']; -const missing = []; -const empty = []; +const errors = []; required.forEach(varName => { - if (!(varName in envVars)) { - missing.push(varName); - } else if (envVars[varName] === '') { - empty.push(varName); + if (!envVars[varName] || envVars[varName] === '') { + errors.push(`Missing: ${varName}`); } }); -// Report errors -if (missing.length > 0) { - console.error('ERROR: Missing required env vars: ' + missing.join(', ')); - console.error('Please add these variables to your .env file'); - process.exit(1); -} - -if (empty.length > 0) { - console.error('ERROR: Empty values for env vars: ' + empty.join(', ')); - console.error('Please provide values for these variables in your .env file'); +if (errors.length > 0) { + console.error('ERROR: Required environment variables missing:'); + errors.forEach(err => console.error(` - ${err}`)); + console.error('\nPlease add these to your .env file'); process.exit(1); } -// Validate URL format for SUPABASE_URL +// Validate URL format try { new URL(envVars['SUPABASE_URL']); } catch (e) { - console.error('ERROR: SUPABASE_URL is not a valid URL: ' + envVars['SUPABASE_URL']); + console.error('ERROR: SUPABASE_URL is not a valid URL'); + console.error(` Found: ${envVars['SUPABASE_URL']}`); + console.error(' Expected format: https://your-project.supabase.co'); process.exit(1); } -// Basic validation for service key (should be non-trivial) +// Basic validation for service key if (envVars['SUPABASE_SERVICE_KEY'].length < 10) { console.error('ERROR: SUPABASE_SERVICE_KEY appears to be invalid (too short)'); + console.error(' Please check your Supabase project settings'); process.exit(1); } -console.log('Environment OK: SUPABASE_URL and SUPABASE_SERVICE_KEY found and validated.'); \ No newline at end of file +console.log('✓ Environment configured correctly'); \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index a32bc0f130..0155726e5d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,10 +16,7 @@ services: args: BUILDKIT_INLINE_CACHE: 1 ARCHON_SERVER_PORT: ${ARCHON_SERVER_PORT:-8181} - container_name: ${ARCHON_SERVER_CONTAINER_NAME:-archon-server} - labels: - - "archon.service=server" - - "archon.type=api" + container_name: archon-server ports: - "${ARCHON_SERVER_PORT:-8181}:${ARCHON_SERVER_PORT:-8181}" environment: @@ -74,10 +71,7 @@ services: args: BUILDKIT_INLINE_CACHE: 1 ARCHON_MCP_PORT: ${ARCHON_MCP_PORT:-8051} - container_name: ${ARCHON_MCP_CONTAINER_NAME:-archon-mcp} - labels: - - "archon.service=mcp" - - "archon.type=protocol" + container_name: archon-mcp ports: - "${ARCHON_MCP_PORT:-8051}:${ARCHON_MCP_PORT:-8051}" environment: @@ -122,10 +116,7 @@ services: args: BUILDKIT_INLINE_CACHE: 1 ARCHON_AGENTS_PORT: ${ARCHON_AGENTS_PORT:-8052} - container_name: ${ARCHON_AGENTS_CONTAINER_NAME:-archon-agents} - labels: - - "archon.service=agents" - - "archon.type=ai" + container_name: archon-agents ports: - "${ARCHON_AGENTS_PORT:-8052}:${ARCHON_AGENTS_PORT:-8052}" environment: @@ -155,10 +146,7 @@ services: frontend: profiles: ["frontend", "full"] build: ./archon-ui-main - container_name: ${ARCHON_UI_CONTAINER_NAME:-archon-ui} - labels: - - "archon.service=ui" - - "archon.type=frontend" + container_name: archon-ui ports: - "${ARCHON_UI_PORT:-3737}:3737" environment: diff --git a/python/src/server/api_routes/mcp_api.py b/python/src/server/api_routes/mcp_api.py index 066819ac30..db43496cdb 100644 --- a/python/src/server/api_routes/mcp_api.py +++ b/python/src/server/api_routes/mcp_api.py @@ -63,50 +63,20 @@ def __init__(self): self._initialize_docker_client() def _resolve_container(self): - """Dynamically resolve the MCP container using multiple strategies.""" + """Simple container resolution - just use fixed name.""" if not self.docker_client: return None - - import os - - # Strategy 1: Try environment variable - env_name = os.getenv("ARCHON_MCP_CONTAINER_NAME") - if env_name: - try: - container = self.docker_client.containers.get(env_name) - self.container_name = env_name - mcp_logger.info(f"Found MCP container via env var: {env_name}") - return container - except NotFound: - mcp_logger.warning(f"Container specified in env var not found: {env_name}") - - # Strategy 2: Try finding by label + try: - containers = self.docker_client.containers.list( - all=True, - filters={"label": "archon.service=mcp"} - ) - if containers: - container = containers[0] - self.container_name = container.name - mcp_logger.info(f"Found MCP container via label: {self.container_name}") - return container - except Exception as e: - mcp_logger.debug(f"Label search failed: {e}") - - # Strategy 3: Try known container names (backward compatibility) - fallback_names = ["archon-mcp", "Archon-MCP"] - for name in fallback_names: - try: - container = self.docker_client.containers.get(name) - self.container_name = name - mcp_logger.info(f"Found MCP container via fallback name: {name}") - return container - except NotFound: - continue - - mcp_logger.warning("Could not find MCP container using any strategy") - return None + # Simple: Just look for the fixed container name + container = self.docker_client.containers.get("archon-mcp") + self.container_name = "archon-mcp" + mcp_logger.info("Found MCP container") + return container + except NotFound: + mcp_logger.warning("MCP container not found - is it running?") + self.container_name = "archon-mcp" + return None def _initialize_docker_client(self): """Initialize Docker client and get container reference.""" From 25bfb68e6d54d8ef739a51754c71715f7aeec709 Mon Sep 17 00:00:00 2001 From: Rasmus Widing Date: Fri, 22 Aug 2025 14:03:45 +0300 Subject: [PATCH 12/15] feat: Add granular test and lint commands to Makefile - Split test command into test-fe and test-be for targeted testing - Split lint command into lint-fe and lint-be for targeted linting - Keep original test and lint commands that run both - Update help text with new commands for better developer experience --- Makefile | 30 +++++++++++++++----- README.md | 82 ++++++++++++++++--------------------------------------- 2 files changed, 47 insertions(+), 65 deletions(-) diff --git a/Makefile b/Makefile index 5459cb34ac..1c18b5addb 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ SHELL := /bin/bash .SHELLFLAGS := -ec -.PHONY: help dev dev-docker stop test lint clean install check +.PHONY: help dev dev-docker stop test test-fe test-be lint lint-fe lint-be clean install check help: @echo "Archon Development Commands" @@ -10,8 +10,12 @@ help: @echo " make dev - Backend in Docker, frontend local (recommended)" @echo " make dev-docker - Everything in Docker" @echo " make stop - Stop all services" - @echo " make test - Run tests" - @echo " make lint - Run linters" + @echo " make test - Run all tests" + @echo " make test-fe - Run frontend tests only" + @echo " make test-be - Run backend tests only" + @echo " make lint - Run all linters" + @echo " make lint-fe - Run frontend linter only" + @echo " make lint-be - Run backend linter only" @echo " make clean - Remove containers and volumes" @echo " make install - Install dependencies" @echo " make check - Check environment setup" @@ -54,17 +58,29 @@ stop: @docker-compose --profile backend --profile frontend --profile full down @echo "✓ Services stopped" -# Run tests -test: +# Run all tests +test: test-fe test-be + +# Run frontend tests +test-fe: @echo "Running frontend tests..." @cd archon-ui-main && npm test + +# Run backend tests +test-be: @echo "Running backend tests..." @cd python && uv run pytest -# Run linters -lint: +# Run all linters +lint: lint-fe lint-be + +# Run frontend linter +lint-fe: @echo "Linting frontend..." @cd archon-ui-main && npm run lint + +# Run backend linter +lint-be: @echo "Linting backend..." @cd python && uv run ruff check --fix diff --git a/README.md b/README.md index 132030fc68..e18f3df701 100644 --- a/README.md +++ b/README.md @@ -74,12 +74,12 @@ This new vision for Archon replaces the old one (the agenteer). Archon used to b 4. **Start Services** (choose one): - **Option A: Full Docker Mode (Recommended for Normal Archon Usage)** + **Full Docker Mode (Recommended for Normal Archon Usage)** ```bash - make prod - # or docker-compose --profile full up --build -d + # or + make dev-docker ``` This starts all core microservices in Docker: @@ -90,14 +90,6 @@ This new vision for Archon replaces the old one (the agenteer). Archon used to b Ports are configurable in your .env as well! - **Option B: Hybrid Development Mode (Recommended for Development)** - - ```bash - make dev - ``` - - This runs backend services in Docker and frontend locally with hot module replacement for instant updates. - 5. **Configure API Keys**: - Open http://localhost:3737 - Go to **Settings** → Select your LLM/embedding provider and set the API key (OpenAI is default) @@ -105,16 +97,16 @@ This new vision for Archon replaces the old one (the agenteer). Archon used to b ### 🚀 Quick Command Reference -| Command | Description | -| ---------------- | ---------------------------------------------------------- | -| `make dev` | Start hybrid dev (backend in Docker, frontend local) ⭐ | -| `make dev-docker`| Everything in Docker | -| `make stop` | Stop all services | -| `make test` | Run all tests | -| `make lint` | Run linters | -| `make install` | Install dependencies | -| `make check` | Check environment setup | -| `make clean` | Remove containers and volumes (with confirmation) | +| Command | Description | +| ----------------- | ------------------------------------------------------- | +| `make dev` | Start hybrid dev (backend in Docker, frontend local) ⭐ | +| `make dev-docker` | Everything in Docker | +| `make stop` | Stop all services | +| `make test` | Run all tests | +| `make lint` | Run linters | +| `make install` | Install dependencies | +| `make check` | Check environment setup | +| `make clean` | Remove containers and volumes (with confirmation) | ## 🔄 Database Reset (Start Fresh if Needed) @@ -283,11 +275,11 @@ Archon uses true microservices architecture with clear separation of concerns: By default, Archon services run on the following ports: -- **Archon-UI**: 3737 -- **Archon-Server**: 8181 -- **Archon-MCP**: 8051 -- **Archon-Agents**: 8052 -- **Archon-Docs**: 3838 (optional) +- **archon-ui**: 3737 +- **archon-server**: 8181 +- **archon-mcp**: 8051 +- **archon-agents**: 8052 +- **archon-docs**: 3838 (optional) ### Changing Ports @@ -349,7 +341,7 @@ make dev # Backend in Docker, frontend local with hot reload # Alternative: Everything in Docker make dev-docker # All services in Docker -# Stop everything +# Stop everything (local FE needs to be stopped manually) make stop ``` @@ -358,13 +350,15 @@ make stop #### Hybrid Mode (Recommended) - `make dev` Best for active development with instant frontend updates: + - Backend services run in Docker (isolated, consistent) - Frontend runs locally with hot module replacement - Instant UI updates without Docker rebuilds #### Full Docker Mode - `make dev-docker` -For testing production-like environment: +For all services in Docker environment: + - All services run in Docker containers - Better for integration testing - Slower frontend updates @@ -411,10 +405,8 @@ lsof -i :3737 # Stop all containers and local services make stop -make stop-local -# Or kill specific process -kill +# Change the port in .env ``` #### Docker Permission Issues (Linux) @@ -437,17 +429,6 @@ newgrp docker git config --global core.autocrlf false ``` -#### Environment Variables Not Loading - -```bash -# Verify .env file exists and has required variables -make doctor - -# Check specific variables -grep SUPABASE_URL .env -grep SUPABASE_SERVICE_KEY .env -``` - #### Frontend Can't Connect to Backend - Check backend is running: `curl http://localhost:8181/health` @@ -468,25 +449,10 @@ docker system prune -f #### Hot Reload Not Working -- **Frontend**: Ensure you're running in hybrid mode (`make dev-hybrid`) for best HMR experience +- **Frontend**: Ensure you're running in hybrid mode (`make dev`) for best HMR experience - **Backend**: Check that volumes are mounted correctly in `docker-compose.yml` - **File permissions**: On some systems, mounted volumes may have permission issues -#### Check Your Setup - -Run the doctor command to validate your environment: - -```bash -make doctor -``` - -This will check: - -- Required tools installation -- Environment variables -- Port availability -- Docker daemon status - ## 📈 Progress

From 687e78b5636220e080a9481765ecb045629d68a8 Mon Sep 17 00:00:00 2001 From: Rasmus Widing Date: Fri, 22 Aug 2025 14:42:06 +0300 Subject: [PATCH 13/15] feat: Improve Docker Compose detection and prefer modern syntax - Prefer 'docker compose' (plugin) over 'docker-compose' (standalone) - Add better error handling in Makefile with proper exit on failures - Add Node.js check before running environment scripts - Pass environment variables correctly to frontend in hybrid mode - Update all documentation to use modern 'docker compose' syntax - Auto-detect which Docker Compose version is available --- Makefile | 28 +++++++++++++++++++--------- README.md | 30 +++++++++++++++++------------- docker-compose.yml | 6 +++--- 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/Makefile b/Makefile index 1c18b5addb..ff5ff99bbd 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,9 @@ SHELL := /bin/bash .SHELLFLAGS := -ec +# Docker compose command - prefer newer 'docker compose' plugin over standalone 'docker-compose' +COMPOSE ?= $(shell docker compose version >/dev/null 2>&1 && echo "docker compose" || echo "docker-compose") + .PHONY: help dev dev-docker stop test test-fe test-be lint lint-fe lint-be clean install check help: @@ -30,24 +33,31 @@ install: # Check environment check: @echo "Checking environment..." + @node -v >/dev/null 2>&1 || { echo "✗ Node.js not found (require Node 18+)."; exit 1; } @node check-env.js @echo "Checking Docker..." - @docker --version > /dev/null 2>&1 && echo "✓ Docker installed" || echo "✗ Docker not found" - @docker-compose --version > /dev/null 2>&1 && echo "✓ Docker Compose installed" || echo "✗ Docker Compose not found" + @docker --version > /dev/null 2>&1 || { echo "✗ Docker not found"; exit 1; } + @$(COMPOSE) version > /dev/null 2>&1 || { echo "✗ Docker Compose not found"; exit 1; } + @echo "✓ Environment OK" + # Hybrid development (recommended) dev: check @echo "Starting hybrid development..." @echo "Backend: Docker | Frontend: Local with hot reload" - @docker-compose --profile backend up -d --build - @echo "Backend running at http://localhost:8181" + @$(COMPOSE) --profile backend up -d --build + @set -a; [ -f .env ] && . ./.env; set +a; \ + echo "Backend running at http://$${HOST:-localhost}:$${ARCHON_SERVER_PORT:-8181}" @echo "Starting frontend..." - @cd archon-ui-main && npm run dev + @cd archon-ui-main && \ + VITE_ARCHON_SERVER_PORT=$${ARCHON_SERVER_PORT:-8181} \ + VITE_ARCHON_SERVER_HOST=$${HOST:-} \ + npm run dev # Full Docker development dev-docker: check @echo "Starting full Docker environment..." - @docker-compose --profile full up -d --build + @$(COMPOSE) --profile full up -d --build @echo "✓ All services running" @echo "Frontend: http://localhost:3737" @echo "API: http://localhost:8181" @@ -55,7 +65,7 @@ dev-docker: check # Stop all services stop: @echo "Stopping all services..." - @docker-compose --profile backend --profile frontend --profile full down + @$(COMPOSE) --profile backend --profile frontend --profile full down @echo "✓ Services stopped" # Run all tests @@ -90,10 +100,10 @@ clean: @read -p "Are you sure? (y/N) " -n 1 -r; \ echo; \ if [[ $$REPLY =~ ^[Yy]$$ ]]; then \ - docker-compose down -v --remove-orphans; \ + $(COMPOSE) down -v --remove-orphans; \ echo "✓ Cleaned"; \ else \ echo "Cancelled"; \ fi -.DEFAULT_GOAL := help \ No newline at end of file +.DEFAULT_GOAL := help diff --git a/README.md b/README.md index e18f3df701..a641f0efa3 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ This new vision for Archon replaces the old one (the agenteer). Archon used to b - [Node.js 18+](https://nodejs.org/) (for hybrid development mode) - [Supabase](https://supabase.com/) account (free tier or local Supabase both work) - [OpenAI API key](https://platform.openai.com/api-keys) (Gemini and Ollama are supported too!) -- [Make](https://www.gnu.org/software/make/) (see [Installing Make](#installing-make) below) +- (OPTIONAL) [Make](https://www.gnu.org/software/make/) (see [Installing Make](#installing-make) below) ### Setup Instructions @@ -77,9 +77,9 @@ This new vision for Archon replaces the old one (the agenteer). Archon used to b **Full Docker Mode (Recommended for Normal Archon Usage)** ```bash - docker-compose --profile full up --build -d + docker compose --profile full up --build -d # or - make dev-docker + make dev-docker # (Alternative: Requires make installed ) ``` This starts all core microservices in Docker: @@ -124,7 +124,7 @@ If you need to completely reset your database and start fresh: 3. **Restart Services**: ```bash - docker-compose --profile full up -d + docker compose --profile full up -d ``` 4. **Reconfigure**: @@ -135,9 +135,9 @@ The reset script safely removes all tables, functions, triggers, and policies wi -## 🛠️ Installing Make +## 🛠️ Installing Make (OPTIONAL) -Make is required for the development workflow. Installation varies by platform: +Make is required for the local development workflow. Installation varies by platform: ### Windows @@ -323,7 +323,7 @@ This is useful when: After changing hostname or ports: -1. Restart Docker containers: `docker-compose down && docker-compose --profile full up -d` +1. Restart Docker containers: `docker compose down && docker compose --profile full up -d` 2. Access the UI at: `http://${HOST}:${ARCHON_UI_PORT}` 3. Update your AI client configuration with the new hostname and MCP port @@ -368,9 +368,13 @@ For all services in Docker environment: ```bash # Run tests make test # Run all tests +make test-fe # Run frontend tests +make test-be # Run backend tests # Run linters make lint # Lint all code +make lint-fe # Lint frontend code +make lint-be # Lint backend code # Check environment make check # Verify environment setup @@ -383,10 +387,10 @@ make clean # Remove containers and volumes (asks for confirmation) ```bash # View logs using Docker Compose directly -docker-compose logs -f # All services -docker-compose logs -f archon-server # API server -docker-compose logs -f archon-mcp # MCP server -docker-compose logs -f archon-ui # Frontend +docker compose logs -f # All services +docker compose logs -f archon-server # API server +docker compose logs -f archon-mcp # MCP server +docker compose logs -f archon-ui # Frontend ``` **Note**: The backend services are configured with `--reload` flag in their uvicorn commands and have source code mounted as volumes for automatic hot reloading when you make changes. @@ -437,11 +441,11 @@ newgrp docker #### Docker Compose Hangs -If `docker-compose` commands hang: +If `docker compose` commands hang: ```bash # Reset Docker Compose -docker-compose down --remove-orphans +docker compose down --remove-orphans docker system prune -f # Restart Docker Desktop (if applicable) diff --git a/docker-compose.yml b/docker-compose.yml index 0155726e5d..98378afdce 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,9 +2,9 @@ # - "backend": Starts only backend services (server, mcp, agents) for hybrid development # - "frontend": Starts only the frontend UI service # - "full": Starts all services for complete Docker deployment -# Use --profile flag with docker-compose to control which services start: -# docker-compose --profile backend up # Backend only for hybrid dev -# docker-compose --profile full up # Everything in Docker +# Use --profile flag to control which services start: +# docker compose --profile backend up # Backend only for hybrid dev (or docker-compose) +# docker compose --profile full up # Everything in Docker (or docker-compose) services: # Server Service (FastAPI + Socket.IO + Crawling) From 199d41899fb71ef15ced5bb469acde8d4466a16a Mon Sep 17 00:00:00 2001 From: Rasmus Widing Date: Fri, 22 Aug 2025 14:53:14 +0300 Subject: [PATCH 14/15] docs: Update CONTRIBUTING.md to reflect simplified development workflow - Add Node.js 18+ as prerequisite for hybrid development - Mark Make as optional throughout the documentation - Update all docker-compose commands to modern 'docker compose' syntax - Add Make command alternatives for testing (make test, test-fe, test-be) - Document make dev for hybrid development mode - Remove linting requirements until codebase errors are resolved --- CONTRIBUTING.md | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d334cc396c..a24ae9cf36 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,8 +53,10 @@ Archon uses true microservices architecture with clear separation of concerns: ### Prerequisites - [Docker Desktop](https://www.docker.com/products/docker-desktop/) +- [Node.js 18+](https://nodejs.org/) (for hybrid development mode) - [Supabase](https://supabase.com/) account (free tier works) - [OpenAI API key](https://platform.openai.com/api-keys) or alternative LLM provider +- (Optional) [Make](https://www.gnu.org/software/make/) for simplified workflows - Basic knowledge of Python (FastAPI) and TypeScript (React) ### Initial Setup @@ -74,7 +76,11 @@ After forking the repository, you'll need to: 3. **Start Development Environment** ```bash - docker-compose up --build -d + # Using Docker Compose directly + docker compose --profile full up --build -d + + # Or using Make (if installed) + make dev-docker ``` 4. **Configure API Keys** @@ -211,14 +217,17 @@ Test these things using both the UI and the MCP server. This process will be sim **Test commands:** ```bash - # Backend tests - cd python && python -m pytest - - # Frontend tests - cd archon-ui-main && npm run test + # Using Make (if installed) + make test # Run all tests + make test-fe # Frontend tests only + make test-be # Backend tests only + + # Or manually + cd python && python -m pytest # Backend tests + cd archon-ui-main && npm run test # Frontend tests # Full integration test - docker-compose up --build -d + docker compose --profile full up --build -d # Test via UI at http://localhost:3737 ``` @@ -324,7 +333,10 @@ Test these things using both the UI and the MCP server. This process will be sim 2. **Testing Your Changes** ```bash - # Run Python tests + # Using Make (if installed) + make test-be + + # Or manually cd python && python -m pytest tests/ # Run specific test categories @@ -334,8 +346,8 @@ Test these things using both the UI and the MCP server. This process will be sim 3. **Code Quality** ```bash - # We encourage you to use linters for all code # Follow service patterns from existing code + # Maintain consistency with the codebase ``` ### Frontend Development (React) @@ -353,7 +365,10 @@ Test these things using both the UI and the MCP server. This process will be sim 2. **Testing Your Changes** ```bash - # Run frontend tests + # Using Make (if installed) + make test-fe + + # Or manually cd archon-ui-main && npm run test # Run with coverage @@ -365,7 +380,10 @@ Test these things using both the UI and the MCP server. This process will be sim 3. **Development Server** ```bash - # For faster iteration, run frontend locally + # Using Make for hybrid mode (if installed) + make dev # Backend in Docker, frontend local + + # Or manually for faster iteration cd archon-ui-main && npm run dev # Still connects to Docker backend services ``` From 73ca87de58753ce7c62d5ace21c0a0a80df5170f Mon Sep 17 00:00:00 2001 From: Rasmus Widing Date: Fri, 22 Aug 2025 16:37:08 +0300 Subject: [PATCH 15/15] fix: Rename frontend service to archon-frontend for consistency Aligns frontend service naming with other services (archon-server, archon-mcp, archon-agents) for better consistency in Docker image naming patterns. --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 98378afdce..28c3f95a04 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -143,7 +143,7 @@ services: start_period: 40s # Frontend - frontend: + archon-frontend: profiles: ["frontend", "full"] build: ./archon-ui-main container_name: archon-ui