# ═══════════════════════════════════════════════════════════ # MicProtocol – Render Blueprint (Backend Only) # Frontend (web + admin) deploys on Vercel separately. # Uses Neon Postgres (external) + Render Redis (add-on). # ═══════════════════════════════════════════════════════════ services: # ─── API (NestJS + tRPC backend) ───────────────────────── - type: web name: micprotocol-api env: node region: frankfurt plan: free buildCommand: corepack enable && pnpm install --frozen-lockfile && pnpm --filter @micprotocol/api prisma:generate && pnpm --filter @micprotocol/api build startCommand: node --max-old-space-size=512 apps/api/dist/main healthCheckPath: /health envVars: - key: NODE_ENV value: production - key: API_PORT value: "4000" - key: DATABASE_URL sync: false - key: REDIS_URL fromService: type: redis name: micprotocol-redis property: connectionString - key: WEB_URL sync: false - key: COOKIE_SECRET generateValue: true - key: CLERK_SECRET_KEY sync: false - key: NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY sync: false - key: RESEND_API_KEY sync: false - key: STRIPE_SECRET_KEY sync: false - key: STRIPE_WEBHOOK_SECRET sync: false - key: SENTRY_DSN sync: false - key: LIVEKIT_API_KEY sync: false - key: LIVEKIT_API_SECRET sync: false - key: LIVEKIT_HOST sync: false - key: LISTMONK_URL sync: false - key: LISTMONK_API_TOKEN sync: false - key: MIC_REALTIME_URL sync: false - key: MIC_REALTIME_INTERNAL_TOKEN sync: false - key: MIC_REALTIME_SHARED_SECRET sync: false # ─── Redis (BullMQ queues + session cache) ─────────────── - type: redis name: micprotocol-redis plan: free maxmemoryPolicy: allkeys-lru # ─── Real-time Collaboration Engine (Erlang/OTP) ────────── # Owns chat fanout, presence, live domain events. Clients connect over # wss:// (Render provides the public URL); the API publishes events via # /internal/dispatch over the internal network. # NOTE: MIC_REALTIME_INTERNAL_TOKEN + MIC_REALTIME_SHARED_SECRET are # required — the service fails closed at startup without them. - type: web name: micprotocol-realtime env: docker region: frankfurt # WARNING: Render free instances sleep after ~15 min of inactivity and # cap at 750 hours/month — a sleeping WS engine drops ALL live sockets. # Use plan: starter (or higher) for real production realtime. plan: free rootDir: services/mic-realtime dockerfilePath: Dockerfile healthCheckPath: /healthz envVars: - key: MIC_REALTIME_PORT value: "4001" - key: MIC_REALTIME_HOST value: "0.0.0.0" - key: MICPROTOCOL_API_URL sync: false - key: MIC_REALTIME_INTERNAL_TOKEN sync: false - key: MIC_REALTIME_SHARED_SECRET sync: false # Browser-facing WebSocket URL — e.g. wss://micprotocol-realtime.onrender.com # (or a custom domain). MUST be wss:// in production, otherwise clients # silently fall back to ws://localhost:4001 and never connect. - key: MIC_REALTIME_PUBLIC_URL sync: false