# Production stack for sehatsahoolat.com — single-host DigitalOcean Droplet.
#
# What runs here:
#   nginx          : TLS termination + reverse proxy for all four upstream apps
#   backend        : NestJS API (private network only)
#   patient-portal : Next.js (served at https://app.sehatsahoolat.com)
#   doctor-portal  : Next.js (served at https://doctor.sehatsahoolat.com)
#   admin-portal   : Next.js (served at https://admin.sehatsahoolat.com)
#   public-site    : Next.js CMS marketing site (served at https://sehatsahoolat.com)
#   redis          : in-cluster cache + rate-limit store (no host port)
#   whisper        : self-hosted faster-whisper for consult transcription
#
# What does NOT run here (intentional split):
#   postgres : DigitalOcean Managed Postgres (external, encrypted, daily backups)
#   spaces   : DigitalOcean Spaces / R2 (S3-compatible object storage)
#   acme.sh  : runs on the host (cron), drops certs into ./nginx/certs/
#
# Bring-up:  docker compose --env-file /etc/sehat/.env -f docker-compose.prod.yml up -d --build
# Restart:   docker compose -f docker-compose.prod.yml restart backend
# Logs:      docker compose -f docker-compose.prod.yml logs -f backend
name: sehat-prod

x-app-defaults: &app-defaults
  restart: unless-stopped
  init: true
  logging:
    driver: json-file
    options:
      max-size: '10m'
      max-file: '5'
  networks: [sehat]

services:
  nginx:
    <<: *app-defaults
    image: nginx:1.27-alpine
    container_name: sehat-nginx
    ports:
      - '80:80'
      - '443:443'
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - ./nginx/certs:/etc/nginx/certs:ro
      - nginx_cache:/var/cache/nginx
    depends_on:
      - backend
      - patient-portal
      - doctor-portal
      - admin-portal
      - public-site

  backend:
    <<: *app-defaults
    build:
      context: ..
      dockerfile: deploy/dockerfiles/Dockerfile.backend
    container_name: sehat-backend
    env_file: [/etc/sehat/.env]
    environment:
      NODE_ENV: production
      PORT: 3000
      # Database — DigitalOcean Managed PG
      DB_HOST: ${DB_HOST}
      DB_PORT: ${DB_PORT:-25060}
      DB_USERNAME: ${DB_USERNAME}
      DB_PASSWORD: ${DB_PASSWORD}
      DB_DATABASE: ${DB_DATABASE}
      DB_SSL: 'true'
      # Redis (internal network only)
      REDIS_HOST: redis
      REDIS_PORT: 6379
      # JWT / sessions — generated by provision.sh, persisted in /etc/sehat/.env
      JWT_SECRET: ${JWT_SECRET}
      JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-12h}
      JWT_REFRESH_SECRET: ${JWT_REFRESH_SECRET}
      JWT_REFRESH_EXPIRES_IN: ${JWT_REFRESH_EXPIRES_IN:-7d}
      ENCRYPTION_KEY: ${ENCRYPTION_KEY}
      API_PUBLIC_URL: ${API_PUBLIC_URL:-https://api.sehatsahoolat.com/api/v2}
      PATIENT_PORTAL_URL: ${PATIENT_PORTAL_URL:-https://app.sehatsahoolat.com}
      DOCTOR_PORTAL_URL: ${DOCTOR_PORTAL_URL:-https://doctor.sehatsahoolat.com}
      ADMIN_PORTAL_URL: ${ADMIN_PORTAL_URL:-https://admin.sehatsahoolat.com}
      PUBLIC_SITE_URL: ${PUBLIC_SITE_URL:-https://sehatsahoolat.com}
      PAYFAST_API_PUBLIC_URL: ${PAYFAST_API_PUBLIC_URL:-https://api.sehatsahoolat.com/api/v2}
      PAYFAST_FRONTEND_SUCCESS_URL: ${PAYFAST_FRONTEND_SUCCESS_URL:-https://app.sehatsahoolat.com/dashboard?payment=success}
      PAYFAST_FRONTEND_CANCEL_URL: ${PAYFAST_FRONTEND_CANCEL_URL:-https://app.sehatsahoolat.com/packages?payment=cancelled}
      PAYFAST_MERCHANT_ID: ${PAYFAST_MERCHANT_ID}
      PAYFAST_SECURED_KEY: ${PAYFAST_SECURED_KEY}
      PAYFAST_STORE_ID: ${PAYFAST_STORE_ID}
      PAYFAST_SECRET_WORD: ${PAYFAST_SECRET_WORD:-}
      PAYFAST_MERCHANT_NAME: ${PAYFAST_MERCHANT_NAME:-Sehat Sahoolat}
      PAYFAST_CURRENCY_CODE: ${PAYFAST_CURRENCY_CODE:-USD}
      # CORS — list of allowed origins, comma-separated
      FRONTEND_URL: ${FRONTEND_URL}
      # Whisper sidecar
      WHISPER_BASE_URL: http://whisper:8001
      # File uploads — bind-mount or S3 via WAL/sidecar
      UPLOAD_DIR: /uploads
    volumes:
      - uploads:/uploads
    depends_on:
      redis:
        condition: service_healthy

  patient-portal:
    <<: *app-defaults
    build:
      context: ..
      dockerfile: deploy/dockerfiles/Dockerfile.nextjs
      args:
        APP_NAME: patient-portal
        PORT: 3001
    container_name: sehat-patient
    env_file: [/etc/sehat/.env]
    environment:
      NODE_ENV: production
      PORT: 3001
      # Server-side API base — backend is on the internal docker network
      NEXT_PUBLIC_API_BASE_URL: https://api.sehatsahoolat.com/api/v2

  doctor-portal:
    <<: *app-defaults
    build:
      context: ..
      dockerfile: deploy/dockerfiles/Dockerfile.nextjs
      args:
        APP_NAME: doctor-portal
        PORT: 3002
    container_name: sehat-doctor
    env_file: [/etc/sehat/.env]
    environment:
      NODE_ENV: production
      PORT: 3002
      NEXT_PUBLIC_API_BASE_URL: https://api.sehatsahoolat.com/api/v2

  admin-portal:
    <<: *app-defaults
    build:
      context: ..
      dockerfile: deploy/dockerfiles/Dockerfile.nextjs
      args:
        APP_NAME: admin-portal
        PORT: 3003
    container_name: sehat-admin
    env_file: [/etc/sehat/.env]
    environment:
      NODE_ENV: production
      PORT: 3003
      NEXT_PUBLIC_API_BASE_URL: https://api.sehatsahoolat.com/api/v2

  public-site:
    <<: *app-defaults
    build:
      context: ..
      dockerfile: deploy/dockerfiles/Dockerfile.nextjs
      args:
        APP_NAME: public-site
        PORT: 3004
    container_name: sehat-public
    env_file: [/etc/sehat/.env]
    environment:
      NODE_ENV: production
      PORT: 3004
      NEXT_PUBLIC_SITE_URL: https://sehatsahoolat.com
      NEXT_PUBLIC_API_BASE_URL: https://api.sehatsahoolat.com/api/v2
      NEXT_PUBLIC_PATIENT_PORTAL_URL: https://app.sehatsahoolat.com
      NEXT_PUBLIC_DOCTOR_PORTAL_URL: https://doctor.sehatsahoolat.com

  redis:
    <<: *app-defaults
    image: redis:7-alpine
    container_name: sehat-redis
    command: ['redis-server', '--requirepass', '${REDIS_PASSWORD}', '--maxmemory', '256mb', '--maxmemory-policy', 'allkeys-lru']
    env_file: [/etc/sehat/.env]
    volumes:
      - redis_data:/data
    healthcheck:
      test: ['CMD-SHELL', 'redis-cli -a "${REDIS_PASSWORD}" ping | grep PONG']
      interval: 15s
      timeout: 4s
      retries: 5

  whisper:
    <<: *app-defaults
    build:
      context: ..
      dockerfile: deploy/dockerfiles/Dockerfile.whisper
    container_name: sehat-whisper
    environment:
      WHISPER_MODEL: ${WHISPER_MODEL:-small}
      WHISPER_DEVICE: ${WHISPER_DEVICE:-cpu}
      WHISPER_COMPUTE_TYPE: ${WHISPER_COMPUTE_TYPE:-int8}
    volumes:
      - whisper_cache:/home/sehat/.cache/huggingface

volumes:
  nginx_cache:
  redis_data:
  whisper_cache:
  uploads:

networks:
  sehat:
    driver: bridge
