# Docker Compose for ManimCat # Production-ready with Redis for task queue and state management version: '3.8' services: redis: image: redis:7-alpine container_name: manim-redis ports: - "${REDIS_PORT:-6379}:6379" volumes: - redis-data:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 600s retries: 10 start_period: 5s command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru networks: - manimcat-network manimcat: build: context: . dockerfile: Dockerfile args: - NODE_ENV=production image: manimcat:latest container_name: manimcat ports: - "${PORT:-3000}:3000" environment: - NODE_ENV=production - PORT=3000 - LOG_LEVEL=${LOG_LEVEL:-info} - PROD_SUMMARY_LOG_ONLY=${PROD_SUMMARY_LOG_ONLY:-true} - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_DB=${REDIS_DB:-0} # Upstream routing (required for server-side generation unless frontend passes customApiConfig) - MANIMCAT_ROUTE_KEYS=${MANIMCAT_ROUTE_KEYS:-} - MANIMCAT_ROUTE_API_URLS=${MANIMCAT_ROUTE_API_URLS:-} - MANIMCAT_ROUTE_API_KEYS=${MANIMCAT_ROUTE_API_KEYS:-} - MANIMCAT_ROUTE_MODELS=${MANIMCAT_ROUTE_MODELS:-} - DISPLAY=:99 volumes: # Persist generated videos - video-storage:/app/public/videos # Temp directory for rendering - manim-tmp:/app/tmp depends_on: redis: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD-SHELL", "node -e \"require('http').get('http://localhost:3000/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))\""] interval: 30s timeout: 600s retries: 3 start_period: 40s networks: - manimcat-network # Resource limits (adjust based on your needs) deploy: resources: limits: cpus: '2' memory: 4G reservations: cpus: '1' memory: 2G networks: manimcat-network: driver: bridge volumes: manim-tmp: driver: local redis-data: driver: local video-storage: driver: local