version: "3.9"

services:
  traefik:
    image: traefik:v3.1
    command:
      - "--providers.docker=true"
      - "--entrypoints.websecure.address=:443"
      - "--entrypoints.web.address=:80"
      - "--certificatesresolvers.le.acme.tlschallenge=true"
      - "--certificatesresolvers.le.acme.email=security@tnt.systems"
      - "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
      - "--api.dashboard=true"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "letsencrypt:/letsencrypt"
    security_opt:
      - no-new-privileges:true
    restart: unless-stopped

  licensing-db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: ltp
      POSTGRES_PASSWORD: ltp_password_change_me
      POSTGRES_DB: licensing
    volumes:
      - dbdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ltp"]
      interval: 10s
      timeout: 5s
      retries: 10
    restart: unless-stopped

  licensing-redis:
    image: redis:7-alpine
    command: ["redis-server", "--appendonly", "yes"]
    volumes:
      - redisdata:/data
    restart: unless-stopped

  licensing-api:
    build: ./services/licensing-api
    environment:
      NODE_ENV: production
      DATABASE_URL: postgresql://ltp:ltp_password_change_me@licensing-db:5432/licensing?schema=public
      PUBLIC_JWT_ALG: EdDSA
      ADMIN_API_KEY: "v8fM6rzV!n4zfTHN^8cCnFhfU!tKxMkmu*SygpedBVZMSUe%!s#PV$BHkT7%mVjT"
      RATE_LIMIT_MAX: "60"
      RATE_LIMIT_TIME_WINDOW: "60" # seconds
    depends_on:
      licensing-db:
        condition: service_healthy
    volumes:
      - keys:/app/keys
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.licensing.rule=Host(`licensing.tnt.systems`)"
      - "traefik.http.routers.licensing.entrypoints=websecure"
      - "traefik.http.routers.licensing.tls.certresolver=le"
      - "traefik.http.services.licensing.loadbalancer.server.port=3000"
      - "traefik.http.middlewares.sec-headers.headers.customResponseHeaders.X-Frame-Options=SAMEORIGIN"
      - "traefik.http.middlewares.sec-headers.headers.customResponseHeaders.X-Content-Type-Options=nosniff"
      - "traefik.http.middlewares.sec-headers.headers.customResponseHeaders.Referrer-Policy=no-referrer-when-downgrade"
      - "traefik.http.routers.licensing.middlewares=sec-headers"
    restart: unless-stopped

volumes:
  letsencrypt:
  dbdata:
  redisdata:
  keys:
