services: postgres: image: postgres:16-alpine container_name: praello-ai-postgres environment: POSTGRES_USER: ${POSTGRES_USER:-enterprise_ai} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-enterprise_ai_secret} POSTGRES_DB: ${POSTGRES_DB:-enterprise_ai} volumes: - postgres_data:/var/lib/postgresql/data ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-enterprise_ai}"] interval: 10s timeout: 5s retries: 5 networks: - praello-ai-network redis: image: redis:7-alpine container_name: praello-ai-redis command: redis-server --appendonly yes volumes: - redis_data:/data ports: - "6379:6379" healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 networks: - praello-ai-network qdrant: image: qdrant/qdrant:v1.12.5 container_name: praello-ai-qdrant volumes: - qdrant_data:/qdrant/storage ports: - "6333:6333" - "6334:6334" healthcheck: test: ["CMD-SHELL", "bash -c 'exec 3<>/dev/tcp/localhost/6333 && echo -e \"GET /readyz HTTP/1.1\\r\\nHost: localhost\\r\\n\\r\\n\" >&3 && head -1 <&3 | grep -q 200'"] interval: 10s timeout: 5s retries: 5 networks: - praello-ai-network backend: build: context: ./backend dockerfile: Dockerfile container_name: praello-ai-backend env_file: - .env environment: DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-enterprise_ai}:${POSTGRES_PASSWORD:-enterprise_ai_secret}@postgres:5432/${POSTGRES_DB:-enterprise_ai} REDIS_URL: redis://redis:6379/0 QDRANT_HOST: qdrant QDRANT_PORT: 6333 volumes: - upload_data:/app/uploads ports: - "8000:8000" depends_on: postgres: condition: service_healthy redis: condition: service_healthy qdrant: condition: service_healthy healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/health/live"] interval: 30s timeout: 10s retries: 3 start_period: 40s networks: - praello-ai-network ingestion-worker: build: context: ./backend dockerfile: Dockerfile container_name: praello-ai-ingestion-worker env_file: - .env environment: DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-enterprise_ai}:${POSTGRES_PASSWORD:-enterprise_ai_secret}@postgres:5432/${POSTGRES_DB:-enterprise_ai} REDIS_URL: redis://redis:6379/0 QDRANT_HOST: qdrant QDRANT_PORT: 6333 INGESTION_CONSUMER_NAME: worker-1 volumes: - upload_data:/app/uploads command: ["python", "-m", "enterprise_ai.worker"] depends_on: postgres: condition: service_healthy redis: condition: service_healthy qdrant: condition: service_healthy networks: - praello-ai-network connector-worker: build: context: ./backend dockerfile: Dockerfile container_name: praello-ai-connector-worker env_file: - .env environment: DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-enterprise_ai}:${POSTGRES_PASSWORD:-enterprise_ai_secret}@postgres:5432/${POSTGRES_DB:-enterprise_ai} REDIS_URL: redis://redis:6379/0 QDRANT_HOST: qdrant QDRANT_PORT: 6333 CONNECTOR_ORGANIZATION_ID: ${CONNECTOR_ORGANIZATION_ID:?set CONNECTOR_ORGANIZATION_ID} CONNECTOR_UPLOADED_BY: ${CONNECTOR_UPLOADED_BY:?set CONNECTOR_UPLOADED_BY} CONNECTOR_SYNC_INTERVAL_SECONDS: ${CONNECTOR_SYNC_INTERVAL_SECONDS:-900} volumes: - upload_data:/app/uploads command: ["python", "-m", "enterprise_ai.connector_worker"] depends_on: postgres: condition: service_healthy redis: condition: service_healthy qdrant: condition: service_healthy networks: - praello-ai-network frontend: build: context: ./frontend dockerfile: Dockerfile container_name: praello-ai-frontend environment: NEXT_PUBLIC_API_URL: http://localhost/api/v1 ports: - "3000:3000" depends_on: backend: condition: service_healthy networks: - praello-ai-network nginx: image: nginx:1.27-alpine container_name: praello-ai-nginx ports: - "80:80" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - backend - frontend networks: - praello-ai-network volumes: postgres_data: redis_data: qdrant_data: upload_data: networks: praello-ai-network: driver: bridge