# =============================================================================
# Britive MCP Gateway — multi-replica stack
# =============================================================================
# Several stateless Gateway replicas behind one TLS edge, all sharing one
# Postgres. This is the production topology expressed in Compose: the same shape
# as the ECS and Kubernetes deployments, on a single host.
#
# USAGE ----------------------------------------------------------------------
#   1. Save this file as docker-compose.yaml
#   2. Create a .env file beside it (see below)
#   3. docker compose up -d --scale gateway=3
#   4. Open https://localhost:8443/
#
# The .env file:
#
#   TENANT=acme
#   GATEWAY_POOL_TOKEN=<your gateway pool token>
#   DATABASE_URL=postgresql://user:pass@your-db-host:5432/gateway
#
# NO SHARED SECRET TO DISTRIBUTE ---------------------------------------------
# Every replica derives its at-rest encryption key from the gateway pool's key,
# which the platform mints and delivers with the pool's settings. Give every
# replica the same pool token — as this file does — and they are guaranteed to
# agree, with nothing generated by hand and nothing to keep stable across
# upgrades.
#
# SETTINGS LIVE ON THE POOL --------------------------------------------------
# Audit sinks, inspection, rate limits, backend policy and the public base URL
# are set in the Britive tenant portal, on the gateway pool this token belongs
# to. Every replica picks a change up on its next sync — within five minutes by
# default — so there is no file to mount and no redeploy.
#
# Set "Public base URL" on that pool to the address clients actually use: the
# TLS edge below, or your own terminator in front of this stack. OAuth redirect
# and resource URLs are built from it.
#
# THE DATABASE ---------------------------------------------------------------
# Point DATABASE_URL at a database you operate — RDS, Cloud SQL, Azure
# Database, or your own Postgres 14+. The commented-out `gateway-postgres`
# service at the bottom is for trying this shape out locally; it is not a
# production database.
#
# NO SESSION AFFINITY -------------------------------------------------------
# All replicas share one database, so any replica can serve any request. The
# edge below round-robins between them with no stickiness configured.
# =============================================================================

name: britive-mcp-gateway

services:
  gateway:
    image: britive/mcp-gateway:latest
    # No container_name and no host ports: this service is scaled to N replicas,
    # both of which must be unique per container.
    environment:
      TENANT: ${TENANT:?TENANT is required, e.g. TENANT=acme}
      # Identical on every replica: it decides which gateway pool they belong
      # to, and therefore which settings and which encryption key they run with.
      GATEWAY_POOL_TOKEN: ${GATEWAY_POOL_TOKEN:?GATEWAY_POOL_TOKEN is required}
      # Your own Postgres. Every replica points at the same one.
      DATABASE_URL: ${DATABASE_URL:?DATABASE_URL is required}
      # Log level until the pool's settings arrive, after which the pool's
      # "Log level" takes over. Everything else comes from the pool.
      LOG_LEVEL: ${LOG_LEVEL:-info}
    expose:
      - "8080"
    healthcheck:
      test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8080/healthz').read()"]
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 20s
    restart: unless-stopped

  tls-edge:
    image: caddy:2.8.4
    # Compose's DNS resolves "gateway" to every replica's address, and Caddy
    # load-balances across all of them. Adding or removing replicas needs no
    # edge change.
    command: >
      caddy reverse-proxy
        --from https://localhost:8443
        --to gateway:8080
        --internal-certs
        --disable-redirects
    ports:
      - "${GATEWAY_PORT:-8443}:8443"
    volumes:
      - caddy-data:/data
    depends_on:
      - gateway
    restart: unless-stopped

  # --- local database, for trying this topology out only ---------------------
  # Uncomment this and set
  #   DATABASE_URL=postgresql://gateway:gateway-local@gateway-postgres:5432/gateway
  # in your .env to run the whole shape on one machine. Do not use it in
  # production: it has no backups, no failover, and a password in a file.
  #
  # gateway-postgres:
  #   image: postgres:17-alpine
  #   environment:
  #     POSTGRES_USER: gateway
  #     POSTGRES_PASSWORD: gateway-local
  #     POSTGRES_DB: gateway
  #   volumes:
  #     - gateway-postgres-data:/var/lib/postgresql/data
  #   healthcheck:
  #     test: ["CMD-SHELL", "pg_isready -U gateway -d gateway"]
  #     interval: 5s
  #     timeout: 3s
  #     retries: 20
  #   restart: unless-stopped

volumes:
  caddy-data:
  # gateway-postgres-data:
