services:
  caddy:
    image: caddy:2.10-alpine
    container_name: classeo_caddy
    environment:
      APP_DOMAIN: ${APP_DOMAIN}
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./deploy/vps/Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config
    depends_on:
      - php
      - frontend
    restart: unless-stopped

  php:
    build:
      context: ./backend
      dockerfile: Dockerfile
      target: prod
    container_name: classeo_php
    environment:
      APP_ENV: prod
      APP_SECRET: ${APP_SECRET}
      TRUSTED_PROXIES: ${TRUSTED_PROXIES}
      TRUSTED_HOSTS: ${TRUSTED_HOSTS}
      DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${MASTER_DATABASE_NAME}?serverVersion=18&charset=utf8
      REDIS_URL: redis://redis:6379
      MESSENGER_TRANSPORT_DSN: doctrine://default?queue_name=async
      MAILER_DSN: ${MAILER_DSN}
      ADMIN_ALERT_EMAIL: ${ADMIN_ALERT_EMAIL}
      DEFAULT_URI: https://${APP_DOMAIN}
      TENANT_BASE_DOMAIN: ${PUBLIC_BASE_DOMAIN}
      APP_URL: https://${APP_DOMAIN}
      CORS_ALLOW_ORIGIN: ${CORS_ALLOW_ORIGIN}
      TURNSTILE_SECRET_KEY: ${TURNSTILE_SECRET_KEY}
      TURNSTILE_FAIL_OPEN: ${TURNSTILE_FAIL_OPEN}
      JWT_SECRET_KEY: /app/config/jwt/private.pem
      JWT_PUBLIC_KEY: /app/config/jwt/public.pem
      JWT_PASSPHRASE: ${JWT_PASSPHRASE}
      LOCK_DSN: redis://redis:6379
      SENTRY_DSN: ${SENTRY_DSN}
      SENTRY_ENVIRONMENT: ${SENTRY_ENVIRONMENT}
      TENANT_CONFIGS: >-
        [{"tenantId":"${TENANT_ID}","subdomain":"${TENANT_SUBDOMAIN}","databaseUrl":"postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${TENANT_DATABASE_NAME}?serverVersion=18&charset=utf8"}]
    volumes:
      - backend_uploads:/app/public/uploads
      - ./backend/config/jwt:/app/config/jwt
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    restart: unless-stopped

  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
      target: prod
    container_name: classeo_frontend
    environment:
      NODE_ENV: production
      HOST: 0.0.0.0
      PORT: 3000
      ORIGIN: https://${APP_DOMAIN}
      PUBLIC_BASE_DOMAIN: ${PUBLIC_BASE_DOMAIN}
      PUBLIC_TURNSTILE_SITE_KEY: ${PUBLIC_TURNSTILE_SITE_KEY}
    depends_on:
      - php
    restart: unless-stopped

  worker:
    build:
      context: ./backend
      dockerfile: Dockerfile
      target: prod
    container_name: classeo_worker
    command:
      - sh
      - -lc
      - until [ -f /app/config/jwt/private.pem ]; do sleep 1; done; php bin/console messenger:consume async --time-limit=3600 --memory-limit=128M -vv
    environment:
      APP_ENV: prod
      APP_SECRET: ${APP_SECRET}
      TRUSTED_PROXIES: ${TRUSTED_PROXIES}
      TRUSTED_HOSTS: ${TRUSTED_HOSTS}
      DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${MASTER_DATABASE_NAME}?serverVersion=18&charset=utf8
      REDIS_URL: redis://redis:6379
      MESSENGER_TRANSPORT_DSN: doctrine://default?queue_name=async
      MAILER_DSN: ${MAILER_DSN}
      ADMIN_ALERT_EMAIL: ${ADMIN_ALERT_EMAIL}
      DEFAULT_URI: https://${APP_DOMAIN}
      TENANT_BASE_DOMAIN: ${PUBLIC_BASE_DOMAIN}
      APP_URL: https://${APP_DOMAIN}
      CORS_ALLOW_ORIGIN: ${CORS_ALLOW_ORIGIN}
      TURNSTILE_SECRET_KEY: ${TURNSTILE_SECRET_KEY}
      TURNSTILE_FAIL_OPEN: ${TURNSTILE_FAIL_OPEN}
      JWT_SECRET_KEY: /app/config/jwt/private.pem
      JWT_PUBLIC_KEY: /app/config/jwt/public.pem
      JWT_PASSPHRASE: ${JWT_PASSPHRASE}
      LOCK_DSN: redis://redis:6379
      SENTRY_DSN: ${SENTRY_DSN}
      SENTRY_ENVIRONMENT: ${SENTRY_ENVIRONMENT}
      TENANT_CONFIGS: >-
        [{"tenantId":"${TENANT_ID}","subdomain":"${TENANT_SUBDOMAIN}","databaseUrl":"postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${TENANT_DATABASE_NAME}?serverVersion=18&charset=utf8"}]
    volumes:
      - ./backend/config/jwt:/app/config/jwt
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
      php:
        condition: service_started
    restart: unless-stopped

  db:
    image: postgres:18.1-alpine
    container_name: classeo_db
    environment:
      POSTGRES_DB: ${MASTER_DATABASE_NAME}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      TENANT_DATABASE_NAME: ${TENANT_DATABASE_NAME}
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./deploy/vps/postgres/01-create-tenant-db.sh:/docker-entrypoint-initdb.d/01-create-tenant-db.sh:ro
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${MASTER_DATABASE_NAME}"]
      interval: 10s
      timeout: 5s
      retries: 10
      start_period: 20s
    restart: unless-stopped

  redis:
    image: redis:7.4-alpine
    container_name: classeo_redis
    command: redis-server --save "" --appendonly no --maxmemory 256mb --maxmemory-policy allkeys-lru
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 10
      start_period: 5s
    restart: unless-stopped

volumes:
  backend_uploads:
  caddy_config:
  caddy_data:
  postgres_data:
  redis_data:
