# Docker Compose for Coolify Deployment
# Deploy all services in one run
#
# Usage in Coolify:
# 1. Create new Docker Compose service
# 2. Point to this file
# 3. Set environment variables in Coolify UI
# 4. Deploy

services:
  # ===========================================
  # DATABASES
  # ===========================================

  postgres-backend:
    image: postgres:16-alpine
    container_name: placebo-postgres-backend
    restart: unless-stopped
    environment:
      POSTGRES_DB: placebo_backend_db
      POSTGRES_USER: placebo_user
      POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
    volumes:
      - placebo-postgres-backend-data:/var/lib/postgresql/data
    expose:
      - "5432"
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U placebo_user -d placebo_backend_db']
      interval: 5s
      timeout: 5s
      retries: 10
      start_period: 30s
    networks:
      - placebo-internal

  postgres-cms:
    image: postgres:16-alpine
    container_name: placebo-postgres-cms
    restart: unless-stopped
    environment:
      POSTGRES_DB: placebo_cms_db
      POSTGRES_USER: placebo_user
      POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
    volumes:
      - placebo-postgres-cms-data:/var/lib/postgresql/data
    expose:
      - "5432"
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U placebo_user -d placebo_cms_db']
      interval: 5s
      timeout: 5s
      retries: 10
      start_period: 30s
    networks:
      - placebo-internal

  # ===========================================
  # BACKEND (NestJS API)
  # ===========================================

  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    container_name: placebo-backend
    restart: unless-stopped
    environment:
      NODE_ENV: production
      PORT: 3000
      DATABASE_TYPE: postgres
      DATABASE_HOST: postgres-backend
      DATABASE_PORT: 5432
      DATABASE_USERNAME: placebo_user
      DATABASE_PASSWORD: ${DATABASE_PASSWORD}
      DATABASE_NAME: placebo_backend_db
      DATABASE_SYNCHRONIZE: 'true'
      DATABASE_LOGGING: 'true'
      JWT_SECRET: ${JWT_SECRET}
      JWT_EXPIRATION: '86400'
      FRONTEND_URL: https://placebo.mk
      PWA_URL: https://app.placebo.mk
      STRAPI_URL: http://cms:1337
      STRAPI_PUBLIC_URL: https://cms.placebo.mk
      VAPID_SUBJECT: ${VAPID_SUBJECT:-mailto:contact@placebo.mk}
      VAPID_PUBLIC_KEY: ${VAPID_PUBLIC_KEY}
      VAPID_PRIVATE_KEY: ${VAPID_PRIVATE_KEY}
    depends_on:
      postgres-backend:
        condition: service_healthy
    healthcheck:
      test: ['CMD', 'node', '-e', "require('http').get('http://127.0.0.1:3000/api/v1/health', (r) => {if(r.statusCode !== 200) process.exit(1)})"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    networks:
      - placebo-internal
      - coolify
    expose:
      - "3000"
    labels:
      - "traefik.enable=true"
      # HTTP router (for Let's Encrypt challenge and redirect)
      - "traefik.http.routers.backend-http.rule=Host(`api.placebo.mk`)"
      - "traefik.http.routers.backend-http.entrypoints=http"
      - "traefik.http.routers.backend-http.middlewares=redirect-to-https"
      # HTTPS router
      - "traefik.http.routers.backend.rule=Host(`api.placebo.mk`)"
      - "traefik.http.routers.backend.entrypoints=https"
      - "traefik.http.routers.backend.tls=true"
      - "traefik.http.routers.backend.tls.certresolver=letsencrypt"
      - "traefik.http.routers.backend.service=backend"
      # Service
      - "traefik.http.services.backend.loadbalancer.server.port=3000"
      # Redirect middleware
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true"

  # ===========================================
  # CMS (Strapi)
  # ===========================================

  cms:
    build:
      context: ./cms/cms
      dockerfile: Dockerfile
    container_name: placebo-cms
    restart: unless-stopped
    environment:
      NODE_ENV: production
      HOST: 0.0.0.0
      PORT: 1337
      PUBLIC_URL: https://cms.placebo.mk
      BACKEND_WEBHOOK_URL: http://backend:3000
      DATABASE_CLIENT: postgres
      DATABASE_HOST: postgres-cms
      DATABASE_PORT: '5432'
      DATABASE_NAME: placebo_cms_db
      DATABASE_USERNAME: placebo_user
      DATABASE_PASSWORD: ${DATABASE_PASSWORD}
      DATABASE_SSL: 'false'
      APP_KEYS: ${STRAPI_APP_KEYS}
      API_TOKEN_SALT: ${STRAPI_API_TOKEN_SALT}
      ADMIN_JWT_SECRET: ${STRAPI_ADMIN_JWT_SECRET}
      TRANSFER_TOKEN_SALT: ${STRAPI_TRANSFER_TOKEN_SALT}
      JWT_SECRET: ${STRAPI_JWT_SECRET}
      ENCRYPTION_KEY: ${STRAPI_ENCRYPTION_KEY}
    depends_on:
      postgres-cms:
        condition: service_healthy
    volumes:
      - placebo-cms-uploads:/app/public/uploads
    healthcheck:
      test: ['CMD', 'node', '-e', "require('http').get('http://127.0.0.1:1337/_health', (r) => {if(r.statusCode === 200 || r.statusCode === 204) process.exit(0); process.exit(1)})"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
    networks:
      - placebo-internal
      - coolify
    expose:
      - "1337"
    labels:
      - "traefik.enable=true"
      # HTTP router (for Let's Encrypt challenge and redirect)
      - "traefik.http.routers.cms-http.rule=Host(`cms.placebo.mk`)"
      - "traefik.http.routers.cms-http.entrypoints=http"
      - "traefik.http.routers.cms-http.middlewares=redirect-to-https"
      # HTTPS router
      - "traefik.http.routers.cms.rule=Host(`cms.placebo.mk`)"
      - "traefik.http.routers.cms.entrypoints=https"
      - "traefik.http.routers.cms.tls=true"
      - "traefik.http.routers.cms.tls.certresolver=letsencrypt"
      - "traefik.http.routers.cms.service=cms"
      # Service configuration
      - "traefik.http.services.cms.loadbalancer.server.port=1337"
      - "traefik.http.services.cms.loadbalancer.passhostheader=true"
      - "traefik.http.services.cms.loadbalancer.responseForwarding.flushInterval=100ms"
      # Health check for service
      - "traefik.http.services.cms.loadbalancer.healthcheck.path=/_health"
      - "traefik.http.services.cms.loadbalancer.healthcheck.interval=30s"
      - "traefik.http.services.cms.loadbalancer.healthcheck.timeout=5s"

  # ===========================================
  # FRONTEND (React)
  # ===========================================

  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
      args:
        VITE_API_URL: https://api.placebo.mk/api/v1
        VITE_CMS_URL: https://cms.placebo.mk
        VITE_PUBLIC_POSTHOG_KEY: phc_kuDGT1kUmJmijLRjiQaKWIaU4JBdFW0aELW2hIGlBXR
        VITE_PUBLIC_POSTHOG_HOST: https://eu.i.posthog.com
    container_name: placebo-frontend
    restart: unless-stopped
    depends_on:
      - backend
    healthcheck:
      test: ['CMD', 'wget', '--no-verbose', '--tries=1', '--spider', 'http://127.0.0.1:80/']
      interval: 30s
      timeout: 10s
      retries: 3
    networks:
      - placebo-internal
      - coolify
    expose:
      - "80"
    labels:
      - "traefik.enable=true"
      # HTTP router (for Let's Encrypt challenge and redirect)
      - "traefik.http.routers.frontend-http.rule=Host(`placebo.mk`) || Host(`www.placebo.mk`)"
      - "traefik.http.routers.frontend-http.entrypoints=http"
      - "traefik.http.routers.frontend-http.middlewares=redirect-to-https"
      # HTTPS router
      - "traefik.http.routers.frontend.rule=Host(`placebo.mk`) || Host(`www.placebo.mk`)"
      - "traefik.http.routers.frontend.entrypoints=https"
      - "traefik.http.routers.frontend.tls=true"
      - "traefik.http.routers.frontend.tls.certresolver=letsencrypt"
      - "traefik.http.routers.frontend.service=frontend"
      # Service
      - "traefik.http.services.frontend.loadbalancer.server.port=80"

  # ===========================================
  # PWA (Progressive Web App)
  # ===========================================

  pwa:
    build:
      context: ./pwa
      dockerfile: Dockerfile
      args:
        VITE_API_URL: https://api.placebo.mk/api/v1
        VITE_CMS_URL: https://cms.placebo.mk
        VITE_PUBLIC_POSTHOG_KEY: phc_kuDGT1kUmJmijLRjiQaKWIaU4JBdFW0aELW2hIGlBXR
        VITE_PUBLIC_POSTHOG_HOST: https://eu.i.posthog.com
    container_name: placebo-pwa
    restart: unless-stopped
    depends_on:
      - backend
    healthcheck:
      test: ['CMD', 'wget', '--no-verbose', '--tries=1', '--spider', 'http://127.0.0.1:80/']
      interval: 30s
      timeout: 10s
      retries: 3
    networks:
      - placebo-internal
      - coolify
    expose:
      - "80"
    labels:
      - "traefik.enable=true"
      # HTTP router (for Let's Encrypt challenge and redirect)
      - "traefik.http.routers.pwa-http.rule=Host(`app.placebo.mk`)"
      - "traefik.http.routers.pwa-http.entrypoints=http"
      - "traefik.http.routers.pwa-http.middlewares=redirect-to-https"
      # HTTPS router
      - "traefik.http.routers.pwa.rule=Host(`app.placebo.mk`)"
      - "traefik.http.routers.pwa.entrypoints=https"
      - "traefik.http.routers.pwa.tls=true"
      - "traefik.http.routers.pwa.tls.certresolver=letsencrypt"
      - "traefik.http.routers.pwa.service=pwa"
      # Service
      - "traefik.http.services.pwa.loadbalancer.server.port=80"

# ===========================================
# VOLUMES (Managed by Coolify)
# ===========================================

volumes:
  placebo-postgres-backend-data:
    driver: local
  placebo-postgres-cms-data:
    driver: local
  placebo-cms-uploads:
    driver: local

# ===========================================
# NETWORKS
# ===========================================

networks:
  placebo-internal:
    driver: bridge
  coolify:
    external: true
