version: '3.8'

services:
  mysql:
    image: mysql:8.0
    container_name: ibw_mysql_prod
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${DB_NAME}
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASSWORD}
    volumes:
      - mysql_prod_data:/var/lib/mysql
      - ./docker/mysql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
    deploy:
      resources:
        limits:
          cpus: '2.00'
          memory: 2G
        reservations:
          cpus: '0.50'
          memory: 512M
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - ibw_internal

  redis:
    image: redis:7-alpine
    container_name: ibw_redis_prod
    restart: always
    command: redis-server --requirepass ${REDIS_PASSWORD} --appendonly yes
    volumes:
      - redis_prod_data:/data
    deploy:
      resources:
        limits:
          cpus: '1.00'
          memory: 1G
        reservations:
          cpus: '0.25'
          memory: 256M
    healthcheck:
      test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - ibw_internal

  meilisearch:
    image: getmeili/meilisearch:v1.6
    container_name: ibw_meilisearch_prod
    restart: always
    environment:
      MEILI_MASTER_KEY: ${MEILI_MASTER_KEY}
      MEILI_ENV: production
    volumes:
      - meili_prod_data:/meili_data
    deploy:
      resources:
        limits:
          cpus: '2.00'
          memory: 2G
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:7700/health"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - ibw_internal

  backend:
    build:
      context: .
      dockerfile: ./apps/backend/Dockerfile
    container_name: ibw_backend_prod
    restart: always
    environment:
      NODE_ENV: production
      PORT: 5000
      DB_HOST: mysql
      DB_PORT: 3306
      DB_USER: ${DB_USER}
      DB_PASSWORD: ${DB_PASSWORD}
      DB_NAME: ${DB_NAME}
      DATABASE_URL: mysql://${DB_USER}:${DB_PASSWORD}@mysql:3306/${DB_NAME}
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_PASSWORD: ${REDIS_PASSWORD}
      MEILI_HOST: http://meilisearch:7700
      MEILI_MASTER_KEY: ${MEILI_MASTER_KEY}
      ASSET_STORAGE_DIR: /app/storage
      ASSET_PUBLIC_BASE_URL: /assets
      JWT_SECRET: ${JWT_SECRET}
      JWT_REFRESH_SECRET: ${JWT_REFRESH_SECRET}
    deploy:
      replicas: 2
      resources:
        limits:
          cpus: '1.50'
          memory: 1.5G
    depends_on:
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy
      meilisearch:
        condition: service_healthy
    volumes:
      - catalog_prod_storage:/app/storage
    networks:
      - ibw_internal

  frontend:
    build:
      context: .
      dockerfile: ./apps/frontend/Dockerfile
    container_name: ibw_frontend_prod
    restart: always
    environment:
      NODE_ENV: production
      NEXT_PUBLIC_API_URL: ${API_BASE_URL}
    deploy:
      replicas: 2
      resources:
        limits:
          cpus: '1.00'
          memory: 1G
    depends_on:
      - backend
    networks:
      - ibw_internal

  nginx:
    image: nginx:alpine
    container_name: ibw_nginx_prod
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./docker/nginx/ssl:/etc/nginx/ssl:ro
    depends_on:
      - frontend
      - backend
    networks:
      - ibw_internal

volumes:
  mysql_prod_data:
  redis_prod_data:
  meili_prod_data:
  catalog_prod_storage:

networks:
  ibw_internal:
    driver: bridge
