# =============================================================================
# Britive MCP Gateway — quickstart stack
# =============================================================================
# The Gateway, a database, and a TLS edge. Nothing else. For evaluating the
# Gateway on one machine; see the production guides for a real deployment.
#
# USAGE ----------------------------------------------------------------------
#   1. Save this file as docker-compose.yaml
#   2. Create a .env file beside it (see below)
#   3. docker compose up -d
#   4. Open https://localhost:8443/
#
# The .env file needs two values from your Britive tenant:
#
#   TENANT=acme
#   GATEWAY_POOL_TOKEN=<your gateway pool token>
#
# That is all. Every other setting lives on the gateway pool your token belongs
# to, and the container fetches it from the tenant at startup — including the key
# that protects stored tokens and sessions, so there is nothing to generate and
# sign-ins survive a restart on their own.
#
# ONE SETTING TO CHECK ON THE POOL -------------------------------------------
# In the Britive tenant portal, open that gateway pool and set "Public base URL"
# to https://localhost:8443 — the TLS edge below, which is where your browser
# arrives. OAuth redirect and resource URLs are built from it. Left unset, the
# Gateway falls back to http://localhost:8080 (its own port, not the edge's) with
# a warning, and sign-in fails at the callback.
#
# TLS ------------------------------------------------------------------------
# The edge issues its own certificate from Caddy's local certificate authority,
# so there is nothing to install and no certificate to supply. Your browser will
# warn once that the issuer is unknown, which is expected for a local
# evaluation. The Gateway itself publishes no host port: OAuth tokens cross this
# connection, and exposing the plain-HTTP port alongside the edge would defeat
# the point of having one.
#
# BACKENDS -------------------------------------------------------------------
# Backends are not configured here. They are defined on your Britive tenant and
# arrive through synchronisation.
# =============================================================================

name: britive-mcp-gateway

services:
  gateway:
    image: britive/mcp-gateway:latest
    environment:
      # --- required ---------------------------------------------------------
      # Your tenant: a bare subdomain ("acme") or a full https:// URL. Derives
      # the platform API URL and both OAuth endpoints.
      TENANT: ${TENANT:?TENANT is required, e.g. TENANT=acme}
      # How the Gateway authenticates its own platform calls (backend sync,
      # tool publishing, audit forwarding). Per-user calls always use the
      # caller's own identity, never this token.
      GATEWAY_POOL_TOKEN: ${GATEWAY_POOL_TOKEN:?GATEWAY_POOL_TOKEN is required}
      # Where the database lives. Always required, and deliberately not held on
      # the pool record: these are your credentials for your database.
      DATABASE_URL: postgresql://gateway:${POSTGRES_PASSWORD:-gateway-quickstart}@gateway-postgres:5432/gateway

      # --- optional ---------------------------------------------------------
      # Log level until the pool's settings arrive, after which the pool's
      # "Log level" takes over.
      LOG_LEVEL: ${LOG_LEVEL:-info}
      # Everything else — the public base URL, audit sinks, inspection, rate
      # limits, backend policy — is set on the gateway pool in the Britive
      # tenant portal, and reaches this container within five minutes of the
      # change. The admin console's Settings tab shows what is in force.
    # No host port: reached through the TLS edge below.
    expose:
      - "8080"
    depends_on:
      gateway-postgres:
        condition: service_healthy
    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

  gateway-postgres:
    image: postgres:17-alpine
    environment:
      POSTGRES_USER: gateway
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-gateway-quickstart}
      POSTGRES_DB: gateway
    volumes:
      # Named volume, so audit history and issued tokens survive `down` / `up`.
      # `docker compose down -v` deletes it.
      - 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

  tls-edge:
    image: caddy:2.8.4
    # --internal-certs issues a certificate from Caddy's own local CA, so this
    # stack needs no certificate files and no mkcert.
    # --disable-redirects keeps it bound to 8443 only, with no HTTP redirect
    # listener this stack has no use for.
    command: >
      caddy reverse-proxy
        --from https://localhost:8443
        --to gateway:8080
        --internal-certs
        --disable-redirects
    ports:
      - "${GATEWAY_PORT:-8443}:8443"
    volumes:
      # Persists the local CA, so the certificate does not change on restart.
      - caddy-data:/data
    depends_on:
      gateway:
        condition: service_healthy
    restart: unless-stopped

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