claude.md
1 # docker/ 2 3 **Context:** Docker & Kubernetes Deployment 4 5 This directory contains Docker configuration and Kubernetes manifests for deploying ECHO to containerized environments. 6 7 ## Purpose 8 9 Docker support enables: 10 - **Containerized Deployment** - Package agents and infrastructure in containers 11 - **Environment Consistency** - Same setup across dev/staging/production 12 - **Orchestration** - Kubernetes deployment for scalability 13 - **Easy Setup** - Docker Compose for local development 14 15 ## Directory Structure 16 17 ``` 18 docker/ 19 ├── claude.md # This file 20 ├── docker-compose.yml # Local development setup 21 └── [individual Dockerfiles for agents] 22 ``` 23 24 Note: Kubernetes manifests are in `../k8s/` directory 25 26 ## Docker Compose Setup 27 28 **Purpose:** Run entire ECHO system locally with Docker 29 30 **File:** `docker-compose.yml` 31 32 ```yaml 33 version: '3.8' 34 35 services: 36 # Infrastructure 37 postgres: 38 image: postgres:16-alpine 39 environment: 40 POSTGRES_DB: echo_org 41 POSTGRES_USER: postgres 42 POSTGRES_PASSWORD: postgres 43 ports: 44 - "5432:5432" 45 volumes: 46 - postgres_data:/var/lib/postgresql/data 47 healthcheck: 48 test: ["CMD-SHELL", "pg_isready -U postgres"] 49 interval: 10s 50 timeout: 5s 51 retries: 5 52 53 redis: 54 image: redis:7-alpine 55 ports: 56 - "6379:6379" 57 volumes: 58 - redis_data:/data 59 healthcheck: 60 test: ["CMD", "redis-cli", "ping"] 61 interval: 10s 62 timeout: 3s 63 retries: 5 64 65 # Agents 66 echo-ceo: 67 build: 68 context: ../agents/ceo 69 dockerfile: Dockerfile 70 depends_on: 71 postgres: 72 condition: service_healthy 73 redis: 74 condition: service_healthy 75 environment: 76 DB_HOST: postgres 77 DB_NAME: echo_org 78 REDIS_HOST: redis 79 OLLAMA_ENDPOINT: http://host.docker.internal:11434 80 command: ["./ceo", "--autonomous"] 81 82 echo-cto: 83 build: 84 context: ../agents/cto 85 dockerfile: Dockerfile 86 depends_on: 87 postgres: 88 condition: service_healthy 89 redis: 90 condition: service_healthy 91 environment: 92 DB_HOST: postgres 93 REDIS_HOST: redis 94 OLLAMA_ENDPOINT: http://host.docker.internal:11434 95 command: ["./cto", "--autonomous"] 96 97 # ... (repeat for other 7 agents) 98 99 # Monitor Dashboard 100 monitor: 101 build: 102 context: ../monitor 103 dockerfile: Dockerfile 104 depends_on: 105 postgres: 106 condition: service_healthy 107 redis: 108 condition: service_healthy 109 ports: 110 - "4000:4000" 111 environment: 112 DB_HOST: postgres 113 REDIS_HOST: redis 114 SECRET_KEY_BASE: ${SECRET_KEY_BASE} 115 116 volumes: 117 postgres_data: 118 redis_data: 119 ``` 120 121 ### Usage 122 123 ```bash 124 # Start all services 125 docker-compose up -d 126 127 # View logs 128 docker-compose logs -f 129 130 # Stop all services 131 docker-compose down 132 133 # Rebuild and restart 134 docker-compose up -d --build 135 136 # Run database migrations 137 docker-compose exec postgres psql -U postgres -d echo_org < migrations.sql 138 ``` 139 140 ## Agent Dockerfile Template 141 142 ```dockerfile 143 # Multi-stage build for smaller image 144 FROM elixir:1.18-alpine AS builder 145 146 # Install build dependencies 147 RUN apk add --no-cache build-base git 148 149 WORKDIR /app 150 151 # Copy shared library first (dependency) 152 COPY ../../shared /app/shared 153 WORKDIR /app/shared 154 RUN mix local.hex --force && \ 155 mix local.rebar --force && \ 156 mix deps.get && \ 157 mix compile 158 159 # Copy agent code 160 WORKDIR /app/agent 161 COPY mix.exs mix.lock ./ 162 RUN mix deps.get --only prod 163 COPY lib lib 164 COPY config config 165 166 # Build escript executable 167 RUN MIX_ENV=prod mix escript.build 168 169 # Runtime stage 170 FROM alpine:latest 171 172 # Install runtime dependencies 173 RUN apk add --no-cache bash openssl ncurses-libs 174 175 WORKDIR /app 176 177 # Copy executable from builder 178 COPY --from=builder /app/agent/agent_name ./agent_name 179 180 # Create non-root user 181 RUN adduser -D -u 1000 echo && \ 182 chown -R echo:echo /app 183 184 USER echo 185 186 # Run agent 187 CMD ["./agent_name", "--autonomous"] 188 ``` 189 190 ## Kubernetes Deployment 191 192 **Location:** `../k8s/` directory 193 194 ### Architecture 195 196 ``` 197 k8s/ 198 ├── namespace.yml # echo-org namespace 199 ├── postgres.yml # PostgreSQL StatefulSet 200 ├── redis.yml # Redis Deployment 201 ├── agents/ 202 │ ├── ceo.yml # CEO agent Deployment 203 │ ├── cto.yml # CTO agent Deployment 204 │ └── ... (other agents) 205 └── monitor.yml # Monitor dashboard Deployment + Service 206 ``` 207 208 ### Namespace 209 210 ```yaml 211 # k8s/namespace.yml 212 apiVersion: v1 213 kind: Namespace 214 metadata: 215 name: echo-org 216 labels: 217 name: echo-org 218 ``` 219 220 ### PostgreSQL StatefulSet 221 222 ```yaml 223 # k8s/postgres.yml 224 apiVersion: apps/v1 225 kind: StatefulSet 226 metadata: 227 name: postgres 228 namespace: echo-org 229 spec: 230 serviceName: postgres 231 replicas: 1 232 selector: 233 matchLabels: 234 app: postgres 235 template: 236 metadata: 237 labels: 238 app: postgres 239 spec: 240 containers: 241 - name: postgres 242 image: postgres:16-alpine 243 ports: 244 - containerPort: 5432 245 env: 246 - name: POSTGRES_DB 247 value: echo_org 248 - name: POSTGRES_USER 249 valueFrom: 250 secretKeyRef: 251 name: postgres-secret 252 key: username 253 - name: POSTGRES_PASSWORD 254 valueFrom: 255 secretKeyRef: 256 name: postgres-secret 257 key: password 258 volumeMounts: 259 - name: postgres-storage 260 mountPath: /var/lib/postgresql/data 261 volumeClaimTemplates: 262 - metadata: 263 name: postgres-storage 264 spec: 265 accessModes: ["ReadWriteOnce"] 266 resources: 267 requests: 268 storage: 10Gi 269 ``` 270 271 ### Agent Deployment Template 272 273 ```yaml 274 # k8s/agents/ceo.yml 275 apiVersion: apps/v1 276 kind: Deployment 277 metadata: 278 name: echo-ceo 279 namespace: echo-org 280 spec: 281 replicas: 1 282 selector: 283 matchLabels: 284 app: echo-ceo 285 role: ceo 286 template: 287 metadata: 288 labels: 289 app: echo-ceo 290 role: ceo 291 spec: 292 containers: 293 - name: ceo 294 image: ghcr.io/your-org/echo-ceo:latest 295 env: 296 - name: DB_HOST 297 value: postgres 298 - name: DB_NAME 299 value: echo_org 300 - name: DB_USER 301 valueFrom: 302 secretKeyRef: 303 name: postgres-secret 304 key: username 305 - name: DB_PASSWORD 306 valueFrom: 307 secretKeyRef: 308 name: postgres-secret 309 key: password 310 - name: REDIS_HOST 311 value: redis 312 - name: OLLAMA_ENDPOINT 313 value: http://ollama-service:11434 314 resources: 315 requests: 316 memory: "256Mi" 317 cpu: "100m" 318 limits: 319 memory: "512Mi" 320 cpu: "500m" 321 livenessProbe: 322 exec: 323 command: 324 - /bin/sh 325 - -c 326 - "pgrep -f ceo" 327 initialDelaySeconds: 30 328 periodSeconds: 30 329 readinessProbe: 330 exec: 331 command: 332 - /bin/sh 333 - -c 334 - "pgrep -f ceo" 335 initialDelaySeconds: 10 336 periodSeconds: 10 337 ``` 338 339 ### Monitor Service 340 341 ```yaml 342 # k8s/monitor.yml 343 apiVersion: v1 344 kind: Service 345 metadata: 346 name: monitor 347 namespace: echo-org 348 spec: 349 type: LoadBalancer 350 ports: 351 - port: 80 352 targetPort: 4000 353 protocol: TCP 354 selector: 355 app: monitor 356 --- 357 apiVersion: apps/v1 358 kind: Deployment 359 metadata: 360 name: monitor 361 namespace: echo-org 362 spec: 363 replicas: 2 364 selector: 365 matchLabels: 366 app: monitor 367 template: 368 metadata: 369 labels: 370 app: monitor 371 spec: 372 containers: 373 - name: monitor 374 image: ghcr.io/your-org/echo-monitor:latest 375 ports: 376 - containerPort: 4000 377 env: 378 - name: DB_HOST 379 value: postgres 380 - name: REDIS_HOST 381 value: redis 382 - name: SECRET_KEY_BASE 383 valueFrom: 384 secretKeyRef: 385 name: monitor-secret 386 key: secret_key_base 387 resources: 388 requests: 389 memory: "512Mi" 390 cpu: "250m" 391 limits: 392 memory: "1Gi" 393 cpu: "1000m" 394 ``` 395 396 ## Deployment Commands 397 398 ### Docker Compose 399 400 ```bash 401 # Quick start for local development 402 ./docker-setup.sh 403 404 # Or manually: 405 cd docker 406 docker-compose up -d 407 408 # Check status 409 docker-compose ps 410 411 # View logs 412 docker-compose logs -f echo-ceo 413 414 # Restart specific service 415 docker-compose restart echo-cto 416 417 # Stop everything 418 docker-compose down 419 420 # Clean up volumes 421 docker-compose down -v 422 ``` 423 424 ### Kubernetes 425 426 ```bash 427 # Create namespace 428 kubectl apply -f k8s/namespace.yml 429 430 # Create secrets 431 kubectl create secret generic postgres-secret \ 432 --from-literal=username=postgres \ 433 --from-literal=password=YOUR_PASSWORD \ 434 -n echo-org 435 436 # Deploy infrastructure 437 kubectl apply -f k8s/postgres.yml 438 kubectl apply -f k8s/redis.yml 439 440 # Wait for infrastructure to be ready 441 kubectl wait --for=condition=ready pod -l app=postgres -n echo-org --timeout=300s 442 kubectl wait --for=condition=ready pod -l app=redis -n echo-org --timeout=300s 443 444 # Deploy agents 445 kubectl apply -f k8s/agents/ 446 447 # Deploy monitor 448 kubectl apply -f k8s/monitor.yml 449 450 # Check status 451 kubectl get pods -n echo-org 452 kubectl get services -n echo-org 453 454 # View logs 455 kubectl logs -f deployment/echo-ceo -n echo-org 456 457 # Access monitor dashboard 458 kubectl port-forward service/monitor 4000:80 -n echo-org 459 # Open http://localhost:4000 460 ``` 461 462 ## Building & Pushing Images 463 464 ### Build Script 465 466 ```bash 467 #!/bin/bash 468 set -euo pipefail 469 470 REGISTRY="ghcr.io/your-org" 471 VERSION=$(cat VERSION) 472 473 # Build all agent images 474 for agent in ceo cto chro operations_head product_manager senior_architect uiux_engineer senior_developer test_lead; do 475 echo "Building echo-$agent:$VERSION..." 476 docker build -t "$REGISTRY/echo-$agent:$VERSION" \ 477 -t "$REGISTRY/echo-$agent:latest" \ 478 -f "agents/$agent/Dockerfile" \ 479 . 480 done 481 482 # Build monitor image 483 echo "Building echo-monitor:$VERSION..." 484 docker build -t "$REGISTRY/echo-monitor:$VERSION" \ 485 -t "$REGISTRY/echo-monitor:latest" \ 486 -f "monitor/Dockerfile" \ 487 . 488 489 echo "Build complete!" 490 ``` 491 492 ### Push to Registry 493 494 ```bash 495 # Login to GitHub Container Registry 496 echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin 497 498 # Push all images 499 for agent in ceo cto chro operations_head product_manager senior_architect uiux_engineer senior_developer test_lead; do 500 docker push "$REGISTRY/echo-$agent:$VERSION" 501 docker push "$REGISTRY/echo-$agent:latest" 502 done 503 504 docker push "$REGISTRY/echo-monitor:$VERSION" 505 docker push "$REGISTRY/echo-monitor:latest" 506 ``` 507 508 ## Environment Configuration 509 510 ### Development (.env.dev) 511 512 ```bash 513 DB_HOST=localhost 514 DB_PORT=5432 515 DB_NAME=echo_org 516 DB_USER=postgres 517 DB_PASSWORD=postgres 518 519 REDIS_HOST=localhost 520 REDIS_PORT=6379 521 522 OLLAMA_ENDPOINT=http://localhost:11434 523 ``` 524 525 ### Production (.env.prod) 526 527 ```bash 528 DB_HOST=postgres.production.internal 529 DB_PORT=5432 530 DB_NAME=echo_org 531 DB_USER=echo_prod 532 DB_PASSWORD=${DB_PASSWORD} # From secret 533 534 REDIS_HOST=redis.production.internal 535 REDIS_PORT=6379 536 537 OLLAMA_ENDPOINT=http://ollama.production.internal:11434 538 ``` 539 540 ## Troubleshooting 541 542 ### Container won't start 543 544 **Debug:** 545 ```bash 546 # Check logs 547 docker logs echo-ceo 548 549 # Interactive shell 550 docker exec -it echo-ceo /bin/sh 551 552 # Check health 553 docker inspect echo-ceo | grep -A 10 Health 554 ``` 555 556 ### Database connection errors 557 558 **Debug:** 559 ```bash 560 # Test from container 561 docker exec echo-ceo psql -h postgres -U postgres -d echo_org -c "SELECT 1" 562 563 # Check network 564 docker network inspect docker_default 565 ``` 566 567 ### Redis connection errors 568 569 **Debug:** 570 ```bash 571 # Test from container 572 docker exec echo-ceo redis-cli -h redis ping 573 574 # Check Redis logs 575 docker logs redis 576 ``` 577 578 ### Image size too large 579 580 **Optimize:** 581 - Use multi-stage builds 582 - Use alpine base images 583 - Clean up build artifacts 584 - Don't copy unnecessary files 585 586 ## LocalCode for Docker Questions 587 588 For quick Docker deployment queries, use **LocalCode** (see `../CLAUDE.md` Rule 8): 589 590 ```bash 591 source ./scripts/llm/localcode_quick.sh 592 lc_start 593 lc_query "How do I build Docker images for ECHO agents?" 594 lc_query "Explain the docker-compose setup" 595 lc_end 596 ``` 597 598 ## Related Documentation 599 600 - **Parent:** [../CLAUDE.md](../CLAUDE.md) - Project overview 601 - **Quick Start:** [../DOCKER_QUICKSTART.md](../DOCKER_QUICKSTART.md) - Docker setup guide 602 - **Scripts:** [../scripts/claude.md](../scripts/claude.md) - docker-setup.sh details 603 604 --- 605 606 **Remember:** Docker is for deployment. For local development, running agents directly is simpler and faster.