armature-framework 0.2.2

A modern, type-safe HTTP framework for Rust inspired by Angular and NestJS. Features dependency injection, decorators, middleware, authentication (JWT/OAuth2/SAML), validation, OpenAPI/Swagger, caching, job queues, and observability.
# Armature Microservices Architecture
# ====================================
# Multi-service setup demonstrating service mesh patterns
#
# Services:
# - API Gateway (Kong or custom)
# - User Service
# - Product Service
# - Order Service
# - Notification Service
# - Shared infrastructure
#
# Usage:
#   docker compose up -d
#   Gateway: http://localhost:8000
#   Kong Admin: http://localhost:8001

version: "3.8"

x-service-defaults: &service-defaults
  restart: unless-stopped
  networks:
    - mesh
  logging:
    driver: json-file
    options:
      max-size: "10m"
      max-file: "3"

x-armature-env: &armature-env
  RUST_LOG: info,armature=debug
  OTEL_EXPORTER_OTLP_ENDPOINT: http://jaeger:4317
  REDIS_URL: redis://redis:6379

services:
  # ============================================
  # API Gateway (Kong)
  # ============================================
  kong:
    image: kong:3.5
    <<: *service-defaults
    environment:
      KONG_DATABASE: "off"
      KONG_DECLARATIVE_CONFIG: /kong/kong.yml
      KONG_PROXY_LISTEN: 0.0.0.0:8000
      KONG_ADMIN_LISTEN: 0.0.0.0:8001
      KONG_LOG_LEVEL: info
    ports:
      - "8000:8000"  # Proxy
      - "8001:8001"  # Admin API
    volumes:
      - ./kong/kong.yml:/kong/kong.yml:ro
    healthcheck:
      test: ["CMD", "kong", "health"]
      interval: 10s
      timeout: 5s
      retries: 5

  # ============================================
  # User Service
  # ============================================
  user-service:
    build:
      context: ../..
      dockerfile: docker/microservices/Dockerfile.service
      args:
        SERVICE_NAME: user_service
    <<: *service-defaults
    environment:
      <<: *armature-env
      SERVICE_NAME: user-service
      PORT: 3000
      DATABASE_URL: postgres://armature:armature@postgres:5432/users
      JWT_SECRET: ${JWT_SECRET:-user-service-secret}
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    deploy:
      replicas: 2
      resources:
        limits:
          cpus: "0.5"
          memory: 256M

  # ============================================
  # Product Service
  # ============================================
  product-service:
    build:
      context: ../..
      dockerfile: docker/microservices/Dockerfile.service
      args:
        SERVICE_NAME: product_service
    <<: *service-defaults
    environment:
      <<: *armature-env
      SERVICE_NAME: product-service
      PORT: 3000
      DATABASE_URL: postgres://armature:armature@postgres:5432/products
      ELASTICSEARCH_URL: http://elasticsearch:9200
    depends_on:
      postgres:
        condition: service_healthy
      elasticsearch:
        condition: service_healthy
    deploy:
      replicas: 2
      resources:
        limits:
          cpus: "0.5"
          memory: 256M

  # ============================================
  # Order Service
  # ============================================
  order-service:
    build:
      context: ../..
      dockerfile: docker/microservices/Dockerfile.service
      args:
        SERVICE_NAME: order_service
    <<: *service-defaults
    environment:
      <<: *armature-env
      SERVICE_NAME: order-service
      PORT: 3000
      DATABASE_URL: postgres://armature:armature@postgres:5432/orders
      RABBITMQ_URL: amqp://armature:armature@rabbitmq:5672
      USER_SERVICE_URL: http://user-service:3000
      PRODUCT_SERVICE_URL: http://product-service:3000
    depends_on:
      postgres:
        condition: service_healthy
      rabbitmq:
        condition: service_healthy
    deploy:
      replicas: 2
      resources:
        limits:
          cpus: "0.5"
          memory: 256M

  # ============================================
  # Notification Service
  # ============================================
  notification-service:
    build:
      context: ../..
      dockerfile: docker/microservices/Dockerfile.service
      args:
        SERVICE_NAME: notification_service
    <<: *service-defaults
    environment:
      <<: *armature-env
      SERVICE_NAME: notification-service
      PORT: 3000
      RABBITMQ_URL: amqp://armature:armature@rabbitmq:5672
      SMTP_HOST: mailhog
      SMTP_PORT: 1025
    depends_on:
      rabbitmq:
        condition: service_healthy
    deploy:
      replicas: 1
      resources:
        limits:
          cpus: "0.25"
          memory: 128M

  # ============================================
  # Background Worker Service
  # ============================================
  worker-service:
    build:
      context: ../..
      dockerfile: docker/microservices/Dockerfile.worker
    <<: *service-defaults
    environment:
      <<: *armature-env
      SERVICE_NAME: worker-service
      RABBITMQ_URL: amqp://armature:armature@rabbitmq:5672
      DATABASE_URL: postgres://armature:armature@postgres:5432/workers
    depends_on:
      rabbitmq:
        condition: service_healthy
      postgres:
        condition: service_healthy
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: "0.5"
          memory: 256M

  # ============================================
  # PostgreSQL
  # ============================================
  postgres:
    image: postgres:16-alpine
    <<: *service-defaults
    environment:
      POSTGRES_USER: armature
      POSTGRES_PASSWORD: armature
      POSTGRES_MULTIPLE_DATABASES: users,products,orders,workers
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./postgres/create-databases.sh:/docker-entrypoint-initdb.d/create-databases.sh:ro
    ports:
      - "5432:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U armature"]
      interval: 10s
      timeout: 5s
      retries: 5

  # ============================================
  # Redis
  # ============================================
  redis:
    image: redis:7-alpine
    <<: *service-defaults
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data
    ports:
      - "6379:6379"
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  # ============================================
  # RabbitMQ
  # ============================================
  rabbitmq:
    image: rabbitmq:3.12-management-alpine
    <<: *service-defaults
    environment:
      RABBITMQ_DEFAULT_USER: armature
      RABBITMQ_DEFAULT_PASS: armature
    volumes:
      - rabbitmq_data:/var/lib/rabbitmq
    ports:
      - "5672:5672"
      - "15672:15672"
    healthcheck:
      test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"]
      interval: 30s
      timeout: 10s
      retries: 5

  # ============================================
  # Elasticsearch
  # ============================================
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.11.3
    <<: *service-defaults
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - "ES_JAVA_OPTS=-Xms256m -Xmx256m"
    volumes:
      - elasticsearch_data:/usr/share/elasticsearch/data
    ports:
      - "9200:9200"
    healthcheck:
      test: ["CMD-SHELL", "curl -s http://localhost:9200/_cluster/health | grep -q 'green\\|yellow'"]
      interval: 30s
      timeout: 10s
      retries: 5

  # ============================================
  # Jaeger (Tracing)
  # ============================================
  jaeger:
    image: jaegertracing/all-in-one:1.52
    <<: *service-defaults
    environment:
      COLLECTOR_OTLP_ENABLED: "true"
    ports:
      - "16686:16686"  # UI
      - "4317:4317"    # OTLP gRPC
      - "4318:4318"    # OTLP HTTP

  # ============================================
  # Mailhog (Email Testing)
  # ============================================
  mailhog:
    image: mailhog/mailhog:latest
    <<: *service-defaults
    ports:
      - "1025:1025"   # SMTP
      - "8025:8025"   # Web UI

networks:
  mesh:
    driver: bridge

volumes:
  postgres_data:
  redis_data:
  rabbitmq_data:
  elasticsearch_data: