opencrates 3.0.1

Enterprise-grade AI-powered Rust development companion with comprehensive automation, monitoring, and deployment capabilities
version: '3.8'

services:
  # OpenCrates Application Server
  opencrates:
    build: 
      context: .
      target: runtime
    container_name: opencrates-app
    ports:
      - "8080:8080"
      - "9090:9090"  # Metrics port
    environment:
      - RUST_LOG=info
      - OPENCRATES_HOST=0.0.0.0
      - OPENCRATES_PORT=8080
      - OPENCRATES_METRICS_PORT=9090
      - OPENCRATES_DATABASE_URL=postgresql://opencrates:${POSTGRES_PASSWORD:-opencrates}@postgres:5432/opencrates
      - OPENCRATES_REDIS_URL=redis://redis:6379
      - OPENCRATES_SECRET_KEY=${OPENCRATES_SECRET_KEY:-your-secret-key-change-in-production}
      - OPENAI_API_KEY=${OPENAI_API_KEY}
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
    volumes:
      - opencrates_data:/app/data
      - opencrates_logs:/app/logs
      - ./config:/app/config:ro
      - ./templates:/app/templates:ro
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - opencrates-network
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    deploy:
      resources:
        limits:
          memory: 2G
          cpus: '1.0'
        reservations:
          memory: 512M

  # PostgreSQL Database
  postgres:
    image: postgres:16-alpine
    container_name: opencrates-db
    environment:
      - POSTGRES_DB=opencrates
      - POSTGRES_USER=opencrates
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-opencrates}
      - POSTGRES_INITDB_ARGS=--auth-host=scram-sha-256
      - PGDATA=/var/lib/postgresql/data/pgdata
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./migrations:/docker-entrypoint-initdb.d:ro
      - ./config/postgres/postgresql.conf:/etc/postgresql/postgresql.conf:ro
    ports:
      - "5432:5432"
    restart: unless-stopped
    networks:
      - opencrates-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U opencrates -d opencrates"]
      interval: 15s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          memory: 1G
          cpus: '0.5'

  # Redis Cache & Session Store
  redis:
    image: redis:7.2-alpine
    container_name: opencrates-cache
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
      - ./config/redis/redis.conf:/usr/local/etc/redis/redis.conf:ro
    restart: unless-stopped
    networks:
      - opencrates-network
    command: redis-server /usr/local/etc/redis/redis.conf
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 15s
      timeout: 3s
      retries: 3
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: '0.25'

  # Prometheus Monitoring
  prometheus:
    image: prom/prometheus:v2.47.0
    container_name: opencrates-prometheus
    ports:
      - "9091:9090"
    volumes:
      - prometheus_data:/prometheus
      - ./config/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - ./config/prometheus/rules:/etc/prometheus/rules:ro
    restart: unless-stopped
    networks:
      - opencrates-network
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--storage.tsdb.retention.time=30d'
      - '--web.enable-lifecycle'
      - '--web.enable-admin-api'
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:9090/-/healthy"]
      interval: 30s
      timeout: 10s
      retries: 3

  # Grafana Dashboard
  grafana:
    image: grafana/grafana-oss:10.1.0
    container_name: opencrates-grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:-admin}
      - GF_USERS_ALLOW_SIGN_UP=false
      - GF_INSTALL_PLUGINS=grafana-piechart-panel
      - GF_SERVER_ROOT_URL=http://localhost:3000
    volumes:
      - grafana_data:/var/lib/grafana
      - ./config/grafana/provisioning:/etc/grafana/provisioning:ro
      - ./config/grafana/dashboards:/var/lib/grafana/dashboards:ro
    restart: unless-stopped
    networks:
      - opencrates-network
    depends_on:
      - prometheus
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:3000/api/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  # Jaeger Distributed Tracing
  jaeger:
    image: jaegertracing/all-in-one:1.49
    container_name: opencrates-jaeger
    ports:
      - "16686:16686"  # Jaeger UI
      - "14268:14268"  # HTTP collector
      - "14250:14250"  # gRPC collector
      - "6831:6831/udp"  # Agent UDP
    environment:
      - COLLECTOR_OTLP_ENABLED=true
      - COLLECTOR_ZIPKIN_HOST_PORT=:9411
    volumes:
      - jaeger_data:/tmp
    networks:
      - opencrates-network
    restart: unless-stopped

  # Elasticsearch for Logging & Search
  elasticsearch:
    image: elasticsearch:8.11.0
    container_name: opencrates-elasticsearch
    environment:
      - discovery.type=single-node
      - ES_JAVA_OPTS=-Xms1g -Xmx1g
      - xpack.security.enabled=false
      - xpack.security.enrollment.enabled=false
      - cluster.routing.allocation.disk.threshold_enabled=false
    ports:
      - "9200:9200"
    volumes:
      - elasticsearch_data:/usr/share/elasticsearch/data
    networks:
      - opencrates-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9200/_cluster/health"]
      interval: 30s
      timeout: 10s
      retries: 5
    deploy:
      resources:
        limits:
          memory: 2G

  # Kibana for Log Visualization
  kibana:
    image: kibana:8.11.0
    container_name: opencrates-kibana
    ports:
      - "5601:5601"
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - SERVER_NAME=kibana
      - SERVER_HOST=0.0.0.0
    networks:
      - opencrates-network
    restart: unless-stopped
    depends_on:
      elasticsearch:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:5601/api/status"]
      interval: 30s
      timeout: 10s
      retries: 5

  # Nginx Reverse Proxy & Load Balancer
  nginx:
    image: nginx:1.25-alpine
    container_name: opencrates-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./config/nginx/conf.d:/etc/nginx/conf.d:ro
      - ./config/ssl:/etc/nginx/ssl:ro
      - nginx_logs:/var/log/nginx
    restart: unless-stopped
    networks:
      - opencrates-network
    depends_on:
      - opencrates
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:80/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  # Development & Testing Services (Profile: development)
  opencrates-dev:
    build:
      context: .
      target: development
    container_name: opencrates-dev
    volumes:
      - .:/app
      - cargo_cache:/usr/local/cargo/registry
      - cargo_git_cache:/usr/local/cargo/git
    working_dir: /app
    networks:
      - opencrates-network
    profiles:
      - development
    environment:
      - RUST_LOG=debug
      - RUST_BACKTRACE=1
      - OPENCRATES_DEV_MODE=true
    command: cargo watch -x run

  # Testing Environment
  opencrates-test:
    build:
      context: .
      target: testing
    container_name: opencrates-test
    volumes:
      - .:/app
      - cargo_cache:/usr/local/cargo/registry
      - test_results:/app/test-results
    working_dir: /app
    networks:
      - opencrates-network
    profiles:
      - testing
    environment:
      - RUST_LOG=debug
      - RUST_BACKTRACE=1
      - TEST_MODE=true
    command: ./scripts/test-all.sh

  # Mailhog for Email Testing (Development)
  mailhog:
    image: mailhog/mailhog:v1.0.1
    container_name: opencrates-mailhog
    ports:
      - "8025:8025"  # Web UI
      - "1025:1025"  # SMTP
    networks:
      - opencrates-network
    restart: unless-stopped
    profiles:
      - development

  # MinIO for S3-Compatible Storage (Development)
  minio:
    image: minio/minio:RELEASE.2023-10-07T15-07-38Z
    container_name: opencrates-minio
    command: server /data --console-address ":9001"
    ports:
      - "9000:9000"  # API
      - "9001:9001"  # Console
    environment:
      - MINIO_ROOT_USER=${MINIO_ROOT_USER:-minioadmin}
      - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD:-minioadmin}
    volumes:
      - minio_data:/data
    networks:
      - opencrates-network
    restart: unless-stopped
    profiles:
      - development
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3

  # Adminer for Database Management (Development)
  adminer:
    image: adminer:4.8.1
    container_name: opencrates-adminer
    ports:
      - "8081:8080"
    networks:
      - opencrates-network
    restart: unless-stopped
    profiles:
      - development
    depends_on:
      - postgres

  # Load Testing with k6
  k6:
    image: grafana/k6:0.46.0
    container_name: opencrates-k6
    volumes:
      - ./scripts/k6:/scripts
      - k6_results:/results
    networks:
      - opencrates-network
    profiles:
      - testing
    depends_on:
      - opencrates
    command: run /scripts/load-test.js

volumes:
  # Application data
  opencrates_data:
    driver: local
  opencrates_logs:
    driver: local
  
  # Database storage
  postgres_data:
    driver: local
  redis_data:
    driver: local
  elasticsearch_data:
    driver: local
  
  # Monitoring & observability
  prometheus_data:
    driver: local
  grafana_data:
    driver: local
  jaeger_data:
    driver: local
  
  # Development & testing
  minio_data:
    driver: local
  cargo_cache:
    driver: local
  cargo_git_cache:
    driver: local
  test_results:
    driver: local
  k6_results:
    driver: local
  
  # Proxy & logs
  nginx_logs:
    driver: local

networks:
  opencrates-network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.20.0.0/16
          gateway: 172.20.0.1