# Deployment Guide — Loyalty Agent Service ## Prerequisites - Java 25+ (JRE) - PostgreSQL 15+ - Ollama with `qwen3.5:4b` and `qwen2.5:1.5b` models - Keycloak with OAuth2 Client Credentials configured - Loyalty Core API running (`:8081`) ## Environment Variables Copy `.env.example` to `.env` and configure all required values: ```bash cp .env.example .env # Edit .env with your production values ``` ### Required Variables | Variable | Service | Description | |----------|---------|-------------| | `KEYCLOAK_CLIENT_SECRET` | MCP Server | Keycloak client secret | | `KEYCLOAK_TOKEN_URI` | MCP Server | Keycloak token endpoint | | `LOYALTY_CORE_BASE_URL` | MCP Server | Loyalty Core API URL | | `SPRING_DATASOURCE_PASSWORD` | Agent | PostgreSQL password | | `MCP_SERVER_URL` | Agent | MCP SSE endpoint | ### Optional Variables (with defaults) | Variable | Default | Description | |----------|---------|-------------| | `KEYCLOAK_CLIENT_ID` | `ols-cli` | OAuth2 client ID | | `SPRING_DATASOURCE_URL` | `jdbc:postgresql://localhost:5433/loyalty_agent` | DB URL | | `SPRING_DATASOURCE_USERNAME` | `postgres` | DB username | | `OLLAMA_BASE_URL` | `http://localhost:11434` | Ollama URL | | `OLLAMA_MODEL` | `qwen3.5:4b` | Primary LLM model | | `AGENT_REQUEST_TIMEOUT` | `120` | LLM request timeout (seconds) | ## Building ```bash # Build both modules ./mvnw clean package -DskipTests # Run tests ./mvnw test ``` ## Running Locally ### Quick Start ```bash ./start-all.sh ``` ### Manual Start ```bash # 1. Start MCP Server (:9331) cd loyalty-mcp-server java -jar target/*.jar # 2. Start Agent (:9332) cd loyalty-agent java -jar target/*.jar # 3. Start Frontend (:9333) npm run dev ``` ## Docker Deployment ### Build Images ```bash # MCP Server cd loyalty-mcp-server docker build -t loyalty-mcp-server:latest . # Agent cd loyalty-agent docker build -t loyalty-agent:latest . ``` ### Run Containers ```bash # MCP Server docker run -d --name loyalty-mcp-server \ -p 9331:9331 \ -e KEYCLOAK_CLIENT_SECRET=... \ -e KEYCLOAK_TOKEN_URI=... \ -e LOYALTY_CORE_BASE_URL=... \ loyalty-mcp-server:latest # Agent docker run -d --name loyalty-agent \ -p 9332:9332 \ -e SPRING_DATASOURCE_PASSWORD=... \ -e MCP_SERVER_URL=http://loyalty-mcp-server:9331/sse \ loyalty-agent:latest ``` ## Health Checks Both services expose health endpoints via Spring Boot Actuator: | Endpoint | Purpose | |----------|---------| | `/actuator/health` | Overall health | | `/actuator/health/liveness` | Liveness probe (is the process alive?) | | `/actuator/health/readiness` | Readiness probe (can it handle requests?) | | `/actuator/info` | Service info | ### Kubernetes Probes ```yaml livenessProbe: httpGet: path: /actuator/health/liveness port: 9332 initialDelaySeconds: 60 periodSeconds: 30 readinessProbe: httpGet: path: /actuator/health/readiness port: 9332 initialDelaySeconds: 30 periodSeconds: 10 ``` ## JVM Configuration Production JVM flags (included in Dockerfile): ```bash java \ -XX:+UseContainerSupport \ -XX:MaxRAMPercentage=75.0 \ -Djava.security.egd=file:/dev/./urandom \ -jar app.jar ``` ## Port Summary | Service | Port | |---------|------| | Loyalty MCP Server | 9331 | | Loyalty Agent | 9332 | | Frontend (dev) | 9333 | | Loyalty Core API | 8081 | ## Troubleshooting ### Common Issues 1. **MCP Connection Timeout**: Increase `spring.ai.mcp.client.request-timeout` (default: 30000ms) 2. **LLM Not Responding**: Check Ollama is running: `curl http://localhost:11434/api/tags` 3. **OAuth2 Token Error**: Verify Keycloak credentials and token-uri 4. **DB Migration Failed**: Check Flyway logs, ensure PostgreSQL is accessible 5. **WebSocket Disconnect**: Frontend auto-reconnects with exponential backoff