Archon/docker-compose.yml
Wirasm 86dd1b0749
Improve development environment with Docker Compose profiles (#435)
* 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

* Refactor development environment setup: replace dev.bat with Makefile for cross-platform support and enhanced commands

* Enhance development environment: add environment variable checks and update test commands for frontend and backend

* 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 <zaksnet@users.noreply.github.com>

* 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.

* 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

* 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 <noreply@anthropic.com>

* 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

* 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

* 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

* refactor: Simplify development workflow based on comprehensive review

- 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)

* 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

* 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

* 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

* 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.

---------

Co-authored-by: Zak Stam <zakscomputers@hotmail.com>
Co-authored-by: Zak Stam <zaksnet@users.noreply.github.com>
2025-08-22 17:18:10 +03:00

173 lines
5.3 KiB
YAML

# 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 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)
archon-server:
profiles: ["backend", "full"]
build:
context: ./python
dockerfile: Dockerfile.server
args:
BUILDKIT_INLINE_CACHE: 1
ARCHON_SERVER_PORT: ${ARCHON_SERVER_PORT:-8181}
container_name: archon-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:-INFO}
- ARCHON_SERVER_PORT=${ARCHON_SERVER_PORT:-8181}
- ARCHON_MCP_PORT=${ARCHON_MCP_PORT:-8051}
- ARCHON_AGENTS_PORT=${ARCHON_AGENTS_PORT:-8052}
networks:
- app-network
volumes:
- /var/run/docker.sock:/var/run/docker.sock # Docker socket for MCP container control
- ./python/src:/app/src # Mount source code for hot reload
- ./python/tests:/app/tests # Mount tests for UI test execution
extra_hosts:
- "host.docker.internal:host-gateway"
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: 30s
timeout: 10s
retries: 3
start_period: 40s
# Lightweight MCP Server Service (HTTP-based)
archon-mcp:
profiles: ["backend", "full"]
build:
context: ./python
dockerfile: Dockerfile.mcp
args:
BUILDKIT_INLINE_CACHE: 1
ARCHON_MCP_PORT: ${ARCHON_MCP_PORT:-8051}
container_name: archon-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:-INFO}
# MCP needs to know where to find other services
- API_SERVICE_URL=http://archon-server:${ARCHON_SERVER_PORT:-8181}
- AGENTS_SERVICE_URL=http://archon-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:
- app-network
depends_on:
- archon-server
- archon-agents
extra_hosts:
- "host.docker.internal:host-gateway"
healthcheck:
test:
[
"CMD",
"sh",
"-c",
'python -c "import socket; s=socket.socket(); s.connect((''localhost'', ${ARCHON_MCP_PORT:-8051})); s.close()"',
]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s # Give dependencies time to start
# AI Agents Service (ML/Reranking)
archon-agents:
profiles: ["backend", "full"]
build:
context: ./python
dockerfile: Dockerfile.agents
args:
BUILDKIT_INLINE_CACHE: 1
ARCHON_AGENTS_PORT: ${ARCHON_AGENTS_PORT:-8052}
container_name: archon-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:-INFO}
- ARCHON_AGENTS_PORT=${ARCHON_AGENTS_PORT:-8052}
networks:
- app-network
healthcheck:
test:
[
"CMD",
"sh",
"-c",
'python -c "import urllib.request; urllib.request.urlopen(''http://localhost:${ARCHON_AGENTS_PORT:-8052}/health'')"',
]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# Frontend
archon-frontend:
profiles: ["frontend", "full"]
build: ./archon-ui-main
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:3737"]
interval: 30s
timeout: 10s
retries: 3
volumes:
- ./archon-ui-main/src:/app/src
- ./archon-ui-main/public:/app/public
depends_on:
- archon-server
networks:
app-network:
driver: bridge