From 120f3d83a70b64d075ee8c2a147e4e3fbf45cada Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 9 Dec 2025 16:10:32 +0100 Subject: [PATCH] fix: Complete production compose with mcp-browser sidecar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add mcp-browser service for LLM-driven browser automation - Add MCP_BROWSER_URL env var for agent-sidecar communication - Add all production env vars (BACKOFF_*, MAX_FILE_SIZE, SHELL_TIMEOUT) - Add mcp_screenshots volume - Keep CIRCUIT_BREAKER_COOLDOWN at 30s (not 300s) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- docker-compose.prod.yml | 63 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index c00cacb..bfb147b 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -2,17 +2,20 @@ version: "3.8" services: agent: - image: gitea.letsbe.solutions/letsbe/letsbe-sysadmin:latest + image: code.letsbe.solutions/letsbe/sysadmin-agent:latest container_name: letsbe-agent environment: # Required: Orchestrator connection - ORCHESTRATOR_URL=${ORCHESTRATOR_URL} - # Registration token for first-time registration (multi-use tokens recommended) + # Registration token (new secure flow) + # Only needed for first-time registration. After registration, + # credentials are persisted to the path below. - REGISTRATION_TOKEN=${REGISTRATION_TOKEN:-} # Credentials path - must match the volume mount for persistence + # Agent runs as root, so ~ expands to /root, but volume is at /home/agent - CREDENTIALS_PATH=/home/agent/.letsbe-agent/credentials.json # Timing (seconds) @@ -25,20 +28,37 @@ services: # Resilience - MAX_CONCURRENT_TASKS=${MAX_CONCURRENT_TASKS:-3} + - BACKOFF_BASE=${BACKOFF_BASE:-1.0} + - BACKOFF_MAX=${BACKOFF_MAX:-60.0} + - CIRCUIT_BREAKER_THRESHOLD=${CIRCUIT_BREAKER_THRESHOLD:-5} - CIRCUIT_BREAKER_COOLDOWN=${CIRCUIT_BREAKER_COOLDOWN:-30} # Security - - ALLOWED_FILE_ROOT=/opt/letsbe + - ALLOWED_FILE_ROOT=${ALLOWED_FILE_ROOT:-/opt/letsbe} + - MAX_FILE_SIZE=${MAX_FILE_SIZE:-10485760} + - SHELL_TIMEOUT=${SHELL_TIMEOUT:-60} - # Playwright + # Playwright browser automation - PLAYWRIGHT_ARTIFACTS_DIR=/opt/letsbe/playwright-artifacts + - PLAYWRIGHT_DEFAULT_TIMEOUT_MS=60000 + - PLAYWRIGHT_NAVIGATION_TIMEOUT_MS=120000 + + # MCP Browser Sidecar connection (for LLM-driven browser control) + - MCP_BROWSER_URL=http://mcp-browser:8931 volumes: + # Docker socket for container management - /var/run/docker.sock:/var/run/docker.sock + + # Host directory mounts for real infrastructure access - /opt/letsbe/env:/opt/letsbe/env - /opt/letsbe/stacks:/opt/letsbe/stacks - /opt/letsbe/nginx:/opt/letsbe/nginx + + # Credential persistence (survives restarts without re-registration) - agent_home:/home/agent/.letsbe-agent + + # Playwright artifacts storage - playwright_artifacts:/opt/letsbe/playwright-artifacts security_opt: @@ -52,9 +72,44 @@ services: limits: cpus: '1.5' memory: 1G + reservations: + cpus: '0.25' + memory: 256M + + mcp-browser: + image: code.letsbe.solutions/letsbe/mcp-browser:latest + container_name: letsbe-mcp-browser + + environment: + - MAX_SESSIONS=${MAX_SESSIONS:-3} + - IDLE_TIMEOUT_SECONDS=${IDLE_TIMEOUT_SECONDS:-300} + - MAX_SESSION_LIFETIME_SECONDS=${MAX_SESSION_LIFETIME_SECONDS:-1800} + - MAX_ACTIONS_PER_SESSION=${MAX_ACTIONS_PER_SESSION:-50} + - LOG_LEVEL=${LOG_LEVEL:-INFO} + - LOG_JSON=${LOG_JSON:-true} + - SCREENSHOTS_DIR=/screenshots + + volumes: + - mcp_screenshots:/screenshots + + security_opt: + - seccomp=unconfined + + restart: unless-stopped + + deploy: + resources: + limits: + cpus: '1.5' + memory: 1G + reservations: + cpus: '0.25' + memory: 256M volumes: agent_home: name: letsbe-agent-home playwright_artifacts: name: letsbe-playwright-artifacts + mcp_screenshots: + name: letsbe-mcp-screenshots