# Production main-host overlay, applied on top of docker-compose.yml on the main host:
#   docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
#
# It (1) publishes caddy 80/443 — there is no host caddy in prod, so the contour caddy
# owns the edge and does its own ACME on CADDY_SITE_ADDRESS — and the gateway bot-link
# :9443 the remote bot dials in over mTLS; and (2) retunes the baseline limits down for the
# 2 vCPU / 1.9 GiB host (GOMAXPROCS=2, smaller memory caps, shorter Prometheus
# retention). The contour launches deliberately undersized at zero players; the added
# node_exporter + Grafana watch host memory so it can be resized at Selectel when
# traffic arrives.
#
# The bot + its VPN sidecar are absent here (the telegram-local profile is not
# activated); the prod bot runs on its own host from docker-compose.bot.yml.

services:
  caddy:
    ports:
      - "80:80"
      - "443:443"
    deploy:
      resources:
        limits:
          memory: 96M

  gateway:
    # Prod pulls the pushed image by tag instead of building locally; the base
    # build: section stays dormant because the deploy always pulls first.
    image: ${REGISTRY:?set REGISTRY}/scrabble-gateway:${TAG:?set TAG}
    ports:
      - "9443:9443"
    environment:
      # 2 vCPU host: align the Go scheduler with the cgroup quota (the baseline's 3-core gateway needs 3 cores).
      GOMAXPROCS: "2"
    deploy:
      resources:
        limits:
          cpus: "2.0"
          memory: 384M

  backend:
    image: ${REGISTRY:?set REGISTRY}/scrabble-backend:${TAG:?set TAG}
    deploy:
      resources:
        limits:
          memory: 384M

  postgres:
    image: ${REGISTRY:?set REGISTRY}/scrabble-postgres:${TAG:?set TAG}
    # Continuous WAL archiving to S3 via pgBackRest (point-in-time recovery), on the prod
    # main host only. archive_mode is gated by PGBACKREST_ARCHIVE_MODE (default "off"), so
    # merging/redeploying this stack does NOT start archiving until the operator arms it:
    # archiving stays inert — and cannot pile WAL onto the disk — until the S3 repository is
    # set up, the stanza is created and the switch is flipped on. See deploy/README.md
    # (point-in-time recovery — arming). Non-secret settings are inline; the endpoint,
    # bucket, region, S3 keys and repository cipher passphrase come from the prod env.sh
    # (deploy/write-prod-env.sh, PROD_ secrets/variables).
    environment:
      PGBACKREST_STANZA: scrabble
      PGBACKREST_PG1_PATH: /var/lib/postgresql/data
      PGBACKREST_REPO1_TYPE: s3
      PGBACKREST_REPO1_PATH: /pgbackrest
      PGBACKREST_REPO1_S3_URI_STYLE: path
      PGBACKREST_REPO1_S3_ENDPOINT: ${PGBACKREST_S3_ENDPOINT:-}
      PGBACKREST_REPO1_S3_PORT: ${PGBACKREST_S3_PORT:-443}
      PGBACKREST_REPO1_S3_BUCKET: ${PGBACKREST_S3_BUCKET:-}
      PGBACKREST_REPO1_S3_REGION: ${PGBACKREST_S3_REGION:-}
      PGBACKREST_REPO1_S3_KEY: ${PGBACKREST_S3_KEY:-}
      PGBACKREST_REPO1_S3_KEY_SECRET: ${PGBACKREST_S3_KEY_SECRET:-}
      PGBACKREST_REPO1_CIPHER_TYPE: aes-256-cbc
      PGBACKREST_REPO1_CIPHER_PASS: ${PGBACKREST_CIPHER_PASS:-}
      PGBACKREST_REPO1_RETENTION_FULL: "30"
      PGBACKREST_COMPRESS_TYPE: zst
      PGBACKREST_LOG_LEVEL_CONSOLE: info
      PGBACKREST_LOG_LEVEL_FILE: "off"
    # archive_command is inert while archive_mode is off, so it is always present and only
    # the mode switches. A forced 5-minute segment switch bounds the recovery point.
    command:
      - postgres
      - -c
      - archive_mode=${PGBACKREST_ARCHIVE_MODE:-off}
      - -c
      - "archive_command=pgbackrest --stanza=scrabble archive-push %p"
      - -c
      - archive_timeout=300
    deploy:
      resources:
        limits:
          memory: 384M

  renderer:
    image: ${REGISTRY:?set REGISTRY}/scrabble-renderer:${TAG:?set TAG}
    deploy:
      resources:
        limits:
          memory: 160M

  validator:
    image: ${REGISTRY:?set REGISTRY}/scrabble-telegram-validator:${TAG:?set TAG}
    deploy:
      resources:
        limits:
          memory: 96M

  landing:
    image: ${REGISTRY:?set REGISTRY}/scrabble-landing:${TAG:?set TAG}
    deploy:
      resources:
        limits:
          memory: 64M

  otelcol:
    deploy:
      resources:
        limits:
          memory: 256M

  prometheus:
    command:
      - --config.file=/etc/prometheus/prometheus.yml
      - --storage.tsdb.retention.time=7d
    deploy:
      resources:
        limits:
          memory: 256M

  tempo:
    deploy:
      resources:
        limits:
          memory: 384M

  grafana:
    deploy:
      resources:
        limits:
          memory: 256M

  postgres_exporter:
    deploy:
      resources:
        limits:
          memory: 64M
