name: m3
services:
  db:
    image: postgres:17-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${POSTGRES_DB:-m3}
      POSTGRES_USER: ${POSTGRES_USER:-postgres}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set a database password}
    ports:
      - "${POSTGRES_PORT:-5432}:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
      interval: 5s
      timeout: 5s
      retries: 10
      start_period: 10s

  rabbitmq:
    image: rabbitmq:4-management-alpine
    restart: unless-stopped
    environment:
      RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER:-m3}
      RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD:?Set a broker password}
    ports:
      - "${RABBITMQ_PORT:-5672}:5672"
      - "${RABBITMQ_MANAGEMENT_PORT:-15672}:15672"
    volumes:
      - rabbitmq_data:/var/lib/rabbitmq
    healthcheck:
      test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"]
      interval: 10s
      timeout: 5s
      retries: 10

  docker-api:
    image: ghcr.io/tecnativa/docker-socket-proxy:v0.5.0
    restart: unless-stopped
    environment:
      CONTAINERS: 1
      IMAGES: 1
      POST: 1
      ALLOW_START: 1
      ALLOW_STOP: 1
      PING: 1
      VERSION: 1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

  app:
    image: ${M3_IMAGE:-sysadminanywhere/m3:latest}
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
      docker-api:
        condition: service_started
      rabbitmq:
        condition: service_healthy
    stop_grace_period: 120s
    environment:
      M3_SECRET_KEY: ${M3_SECRET_KEY:?Set a persistent Base64 AES-256 key}
      M3_ADMIN_PASSWORD: ${M3_ADMIN_PASSWORD:?Set an admin password of 16-72 UTF-8 bytes}
      M3_OPERATOR_PASSWORD: ${M3_OPERATOR_PASSWORD:-}
      M3_VIEWER_PASSWORD: ${M3_VIEWER_PASSWORD:-}
      M3_RETENTION_MESSAGES_DAYS: ${M3_RETENTION_MESSAGES_DAYS:-0}
      M3_RETENTION_IDEMPOTENCY_DAYS: ${M3_RETENTION_IDEMPOTENCY_DAYS:-0}
      M3_RETENTION_RECEIPTS_DAYS: ${M3_RETENTION_RECEIPTS_DAYS:-30}
      M3_RETENTION_AUDIT_DAYS: ${M3_RETENTION_AUDIT_DAYS:-365}
      M3_STORAGE_MODE: ${M3_STORAGE_MODE:-KEEP}
      M3_STORAGE_HOT_DAYS: ${M3_STORAGE_HOT_DAYS:-7}
      M3_ARCHIVE_ENDPOINT: ${M3_ARCHIVE_ENDPOINT:-}
      M3_ARCHIVE_BUCKET: ${M3_ARCHIVE_BUCKET:-m3-messages}
      M3_ARCHIVE_REGION: ${M3_ARCHIVE_REGION:-us-east-1}
      M3_ARCHIVE_ACCESS_KEY: ${M3_ARCHIVE_ACCESS_KEY:-}
      M3_ARCHIVE_SECRET_KEY: ${M3_ARCHIVE_SECRET_KEY:-}
      M3_MASKING_FIELDS: ${M3_MASKING_FIELDS:-password,secret,token,authorization,phone,mobile,cardNumber,pan,cvv,ssn}
      M3_MASKING_JSON_PATHS: ${M3_MASKING_JSON_PATHS:-}
      M3_MASKING_XML_PATHS: ${M3_MASKING_XML_PATHS:-}
      M3_ORIGINAL_READERS: ${M3_ORIGINAL_READERS:-admin}
      M3_LICENSE_PUBLIC_KEY: ${M3_LICENSE_PUBLIC_KEY:-}
      M3_FLOW_MONITOR_WEBHOOK_URL: ${M3_FLOW_MONITOR_WEBHOOK_URL:-}
      M3_FLOW_MONITOR_WEBHOOK_TOKEN: ${M3_FLOW_MONITOR_WEBHOOK_TOKEN:-}
      SPRING_APPLICATION_JSON: ${M3_SERVICES_JSON:-}
      M3_PROCESSING_LOADED_TIMEOUT_SECONDS: ${M3_PROCESSING_LOADED_TIMEOUT_SECONDS:-86400}
      M3_PROCESSING_TIMEOUT_SECONDS: ${M3_PROCESSING_TIMEOUT_SECONDS:-3600}
      M3_PROCESSING_EVENTS_QUEUE: ${M3_PROCESSING_EVENTS_QUEUE:-m3.processing.events}
      M3_PROCESSING_EVENTS_TTL_MS: ${M3_PROCESSING_EVENTS_TTL_MS:-604800000}
      M3_STORAGE_MAX_HOT_BYTES: ${M3_STORAGE_MAX_HOT_BYTES:-0}
      M3_STORAGE_MAX_DATABASE_BYTES: ${M3_STORAGE_MAX_DATABASE_BYTES:-0}
      M3_STORAGE_CATALOG_DAYS: ${M3_STORAGE_CATALOG_DAYS:-0}
      M3_STORAGE_ERROR_MODE: ${M3_STORAGE_ERROR_MODE:-KEEP}
      M3_STORAGE_ERROR_DAYS: ${M3_STORAGE_ERROR_DAYS:-0}
      M3_RETENTION_PROCESSING_EVENTS_DAYS: ${M3_RETENTION_PROCESSING_EVENTS_DAYS:-30}
      M3_RETENTION_MESSAGE_HISTORY_DAYS: ${M3_RETENTION_MESSAGE_HISTORY_DAYS:-0}
      PORT: 8080
      SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/${POSTGRES_DB:-m3}
      SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-postgres}
      SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:?Set a database password}
      SPRING_JPA_HIBERNATE_DDL_AUTO: validate
      SPRING_LIQUIBASE_ENABLED: "true"
      SPRING_JPA_SHOW_SQL: "false"
      VAADIN_LAUNCH_BROWSER: "false"
      SPRING_PROFILES_ACTIVE: prod
      M3_DOCKER_API_URL: http://docker-api:2375
      M3_WORKER_IMAGE: ${M3_IMAGE:-sysadminanywhere/m3:latest}
      M3_WORKER_NETWORK: ${COMPOSE_PROJECT_NAME:-m3}_default
      M3_WORKER_FILES_VOLUME: ${COMPOSE_PROJECT_NAME:-m3}_message_files
      M3_OUTBOUND_MAX_ATTEMPTS: ${M3_OUTBOUND_MAX_ATTEMPTS:-20}
      M3_BROKER_RABBIT_HOST: rabbitmq
      M3_BROKER_RABBIT_USERNAME: ${RABBITMQ_USER:-m3}
      M3_BROKER_RABBIT_PASSWORD: ${RABBITMQ_PASSWORD:?Set a broker password}
    ports:
      - "${M3_PORT:-8080}:8080"
    volumes:
      - message_files:/data

volumes:
  postgres_data:
  rabbitmq_data:
  message_files:
