# docker-compose.federated.yml — Federated tier overlay
#
# USAGE:
#   docker compose -f docker-compose.federated.yml --profile federated up -d
#
# This file is a standalone overlay for the Mosaic federated tier.
# It is NOT an extension of docker-compose.yml — it defines its own services
# and named volumes so it can run independently of the base dev stack.
#
# IMPORTANT — HOST PORT CONFLICTS:
#   The federated services bind the same host ports as the base dev stack
#   (5433 for Postgres, 6380 for Valkey). You must stop the base dev stack
#   before starting the federated stack on the same machine:
#     docker compose down
#     docker compose -f docker-compose.federated.yml --profile federated up -d
#
# pgvector extension:
#   The vector extension is created automatically at first boot via
#   ./infra/pg-init/01-extensions.sql (CREATE EXTENSION IF NOT EXISTS vector).
#
# Tier configuration:
#   Used by `mosaic` instances configured with `tier: federated`.
#   DEFAULT_FEDERATED_CONFIG points at:
#     postgresql://mosaic:mosaic@localhost:5433/mosaic

services:
  postgres-federated:
    image: pgvector/pgvector:pg17
    profiles: [federated]
    restart: unless-stopped
    ports:
      - '${PG_FEDERATED_HOST_PORT:-5433}:5432'
    environment:
      POSTGRES_USER: mosaic
      POSTGRES_PASSWORD: mosaic
      POSTGRES_DB: mosaic
    volumes:
      - pg_federated_data:/var/lib/postgresql/data
      - ./infra/pg-init:/docker-entrypoint-initdb.d:ro
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U mosaic']
      interval: 5s
      timeout: 3s
      retries: 5

  valkey-federated:
    image: valkey/valkey:8-alpine
    profiles: [federated]
    restart: unless-stopped
    ports:
      - '${VALKEY_FEDERATED_HOST_PORT:-6380}:6379'
    volumes:
      - valkey_federated_data:/data
    healthcheck:
      test: ['CMD', 'valkey-cli', 'ping']
      interval: 5s
      timeout: 3s
      retries: 5

  # ---------------------------------------------------------------------------
  # Step-CA — Mosaic Federation internal certificate authority
  #
  # Image: pinned to 0.27.4 (latest stable as of late 2025).
  # `latest` is forbidden per Mosaic image policy (immutable tag required for
  # reproducible deployments and digest-first promotion in CI).
  #
  # Profile: `federated` — this service must not start in non-federated dev.
  #
  # Password:
  #   Dev:  bind-mount ./infra/step-ca/dev-password (gitignored; copy from
  #         ./infra/step-ca/dev-password.example and customise locally).
  #   Prod: replace the bind-mount with a Docker secret:
  #           secrets:
  #             ca_password:
  #               external: true
  #         and reference it as `/run/secrets/ca_password` (same path the
  #         init script already uses).
  #
  # Provisioner: "mosaic-fed" (consumed by apps/gateway/src/federation/ca.service.ts)
  # ---------------------------------------------------------------------------
  step-ca:
    image: smallstep/step-ca:0.27.4
    profiles: [federated]
    restart: unless-stopped
    ports:
      - '${STEP_CA_HOST_PORT:-9000}:9000'
    volumes:
      - step_ca_data:/home/step
      # init script — executed as the container entrypoint
      - ./infra/step-ca/init.sh:/usr/local/bin/mosaic-step-ca-init.sh:ro
      # X.509 template skeleton (wired in M2-04)
      - ./infra/step-ca/templates:/etc/step-ca-templates:ro
      # Dev password file — GITIGNORED; copy from dev-password.example
      # In production, replace this with a Docker secret (see comment above).
      - ./infra/step-ca/dev-password:/run/secrets/ca_password:ro
    entrypoint: ['/bin/sh', '/usr/local/bin/mosaic-step-ca-init.sh']
    healthcheck:
      # The healthcheck requires the root cert to exist, which is only true
      # after init.sh has completed on first boot. start_period gives init
      # time to finish before Docker starts counting retries.
      test:
        [
          'CMD',
          'step',
          'ca',
          'health',
          '--ca-url',
          'https://localhost:9000',
          '--root',
          '/home/step/certs/root_ca.crt',
        ]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

volumes:
  pg_federated_data:
  valkey_federated_data:
  step_ca_data:
