Spaces:
Running
Running
Download docker-compose.yml from Benaah/MicProtocol: direct link, hf CLI and curl.
- Browser
- Download file 32.4 kB
-
https://huggingface.co/spaces/Benaah/MicProtocol/resolve/main/docker-compose.yml
- Command line
-
hf download hf://spaces/Benaah/MicProtocol/docker-compose.yml
-
curl -L -o docker-compose.yml https://huggingface.co/spaces/Benaah/MicProtocol/resolve/main/docker-compose.yml
32.4 kB
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # MicProtocol - Full Stack Docker Compose | |
| # Production-ready orchestration | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| version: "3.8" | |
| services: | |
| # βββ PostgreSQL Database (pgvector β required by Chatwoot + Formbricks) | |
| postgres: | |
| image: pgvector/pgvector:pg16 | |
| container_name: micprotocol-postgres | |
| restart: unless-stopped | |
| environment: | |
| POSTGRES_USER: ${POSTGRES_USER:-micprotocol} | |
| POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-micprotocol_secret} | |
| POSTGRES_DB: ${POSTGRES_DB:-micprotocol} | |
| volumes: | |
| - postgres_data:/var/lib/postgresql/data | |
| - ./scripts/init-databases.sql:/docker-entrypoint-initdb.d/init-databases.sql | |
| ports: | |
| - "5432:5432" | |
| healthcheck: | |
| test: [ "CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-micprotocol}" ] | |
| interval: 10s | |
| timeout: 5s | |
| retries: 5 | |
| networks: | |
| - micprotocol-network | |
| # βββ Redis (Caching & Job Queue) βββββββββββββββββββββββββ | |
| redis: | |
| image: redis:7-alpine | |
| container_name: micprotocol-redis | |
| restart: unless-stopped | |
| command: redis-server --requirepass ${REDIS_PASSWORD:-redis_secret} | |
| volumes: | |
| - redis_data:/data | |
| ports: | |
| - "6379:6379" | |
| healthcheck: | |
| test: [ "CMD", "redis-cli", "ping" ] | |
| interval: 10s | |
| timeout: 3s | |
| retries: 5 | |
| networks: | |
| - micprotocol-network | |
| # βββ Meilisearch (Search Engine) βββββββββββββββββββββββββ | |
| meilisearch: | |
| image: getmeili/meilisearch:v1.6 | |
| container_name: micprotocol-meilisearch | |
| restart: unless-stopped | |
| environment: | |
| MEILI_MASTER_KEY: ${MEILISEARCH_API_KEY:-masterKey} | |
| MEILI_NO_ANALYTICS: "true" | |
| volumes: | |
| - meilisearch_data:/meili_data | |
| ports: | |
| - "7700:7700" | |
| networks: | |
| - micprotocol-network | |
| # βββ API Server ββββββββββββββββββββββββββββββββββββββββββ | |
| api: | |
| build: | |
| context: . | |
| dockerfile: apps/api/Dockerfile | |
| container_name: micprotocol-api | |
| restart: unless-stopped | |
| environment: | |
| NODE_ENV: production | |
| API_PORT: 4000 | |
| DATABASE_URL: postgresql://${POSTGRES_USER:-micprotocol}:${POSTGRES_PASSWORD:-micprotocol_secret}@postgres:5432/${POSTGRES_DB:-micprotocol}?schema=public | |
| REDIS_HOST: redis | |
| REDIS_PORT: 6379 | |
| REDIS_URL: redis://:${REDIS_PASSWORD:-redis_secret}@redis:6379 | |
| REDIS_PASSWORD: ${REDIS_PASSWORD:-redis_secret} | |
| MEILISEARCH_HOST: http://meilisearch:7700 | |
| CLERK_SECRET_KEY: ${CLERK_SECRET_KEY} | |
| CLERK_PUBLISHABLE_KEY: ${CLERK_PUBLISHABLE_KEY} | |
| WEB_URL: ${WEB_URL:-http://localhost:3000} | |
| API_URL: ${API_URL:-http://localhost:4000} | |
| MIC_REALTIME_URL: http://mic-realtime:4001 | |
| MIC_REALTIME_INTERNAL_TOKEN: ${MIC_REALTIME_INTERNAL_TOKEN} | |
| INTERNAL_API_TOKEN: ${INTERNAL_API_TOKEN:-${MIC_REALTIME_INTERNAL_TOKEN}} | |
| MIC_REALTIME_SHARED_SECRET: ${MIC_REALTIME_SHARED_SECRET} | |
| COOKIE_SECRET: ${COOKIE_SECRET:-cookie_secret_change_in_production} | |
| RESEND_API_KEY: ${RESEND_API_KEY} | |
| # Storage | |
| R2_ACCESS_KEY_ID: ${R2_ACCESS_KEY_ID} | |
| R2_SECRET_ACCESS_KEY: ${R2_SECRET_ACCESS_KEY} | |
| R2_ENDPOINT: ${R2_ENDPOINT} | |
| R2_BUCKET: ${R2_BUCKET} | |
| # AI | |
| NVIDIA_NIM_API_KEY: ${NVIDIA_NIM_API_KEY} | |
| DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY} | |
| MOONSHOT_API_KEY: ${MOONSHOT_API_KEY} | |
| # Self-hosted integration URLs (Docker network) | |
| CALCOM_URL: http://calcom:3000 | |
| CHATWOOT_URL: http://chatwoot-web:3000 | |
| DOCUMENSO_URL: http://documenso:3000 | |
| FORMBRICKS_URL: http://formbricks:3000 | |
| LISTMONK_URL: http://listmonk:9000 | |
| UMAMI_URL: http://umami:3000 | |
| LIVEKIT_HOST: http://livekit:7880 | |
| LIVEKIT_URL: http://livekit:7880 | |
| PRETIX_URL: http://pretix:8000 | |
| STRIPE_SECRET_KEY: ${STRIPE_SECRET_KEY} | |
| ports: | |
| - "4000:4000" | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| redis: | |
| condition: service_healthy | |
| healthcheck: | |
| test: [ "CMD", "wget", "-q", "--spider", "http://localhost:4000/health" ] | |
| interval: 30s | |
| timeout: 10s | |
| retries: 3 | |
| start_period: 40s | |
| networks: | |
| - micprotocol-network | |
| deploy: | |
| resources: | |
| limits: | |
| cpus: "2" | |
| memory: 2G | |
| reservations: | |
| cpus: "0.5" | |
| memory: 512M | |
| # βββ Background Workers ββββββββββββββββββββββββββββββββββ | |
| # Same image/entrypoint as `api`, published without ports: a plain | |
| # second instance of the app whose role is queue processing. main.js | |
| # registers the BullMQ WorkerHosts, including the clip-scoring | |
| # processor which spawns the Python pipeline via execFile β see | |
| # apps/api/src/queue/clip-scoring.processor.ts. The Python ML stack | |
| # baked into this image is what actually serves CLIP scoring. The | |
| # previous `npx bullmq` command never worked (the package ships no | |
| # CLI). | |
| worker: | |
| build: | |
| context: . | |
| dockerfile: apps/api/Dockerfile | |
| container_name: micprotocol-worker | |
| restart: unless-stopped | |
| command: node /app/apps/api/dist/main.js | |
| ipc: host | |
| environment: | |
| NODE_ENV: production | |
| DATABASE_URL: postgresql://${POSTGRES_USER:-micprotocol}:${POSTGRES_PASSWORD:-micprotocol_secret}@postgres:5432/${POSTGRES_DB:-micprotocol}?schema=public | |
| REDIS_HOST: redis | |
| REDIS_PORT: 6379 | |
| REDIS_PASSWORD: ${REDIS_PASSWORD:-redis_secret} | |
| MEILISEARCH_HOST: http://meilisearch:7700 | |
| MEILISEARCH_URL: http://meilisearch:7700 | |
| NVIDIA_NIM_API_KEY: ${NVIDIA_NIM_API_KEY} | |
| DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY} | |
| MOONSHOT_API_KEY: ${MOONSHOT_API_KEY} | |
| RESEND_API_KEY: ${RESEND_API_KEY} | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| redis: | |
| condition: service_healthy | |
| networks: | |
| - micprotocol-network | |
| deploy: | |
| resources: | |
| limits: | |
| # Python CLIP/BART inference runs inside this container; the | |
| # 1G limit starved torch and got OOM-killed mid-scoring. | |
| cpus: "2" | |
| memory: 2G | |
| # βββ Erlang/OTP Real-time Collaboration Engine βββββββββ | |
| # Owns chat fanout, presence, live domain events. The NestJS API | |
| # publishes into it via /internal/dispatch; the web client opens | |
| # a WebSocket at /ws?token=... to subscribe to conversations. | |
| mic-realtime: | |
| build: | |
| context: ./services/mic-realtime | |
| dockerfile: Dockerfile | |
| container_name: micprotocol-mic-realtime | |
| restart: unless-stopped | |
| environment: | |
| MIC_REALTIME_PORT: 4001 | |
| MIC_REALTIME_HOST: 0.0.0.0 | |
| MICPROTOCOL_API_URL: ${API_URL:-http://api:4000} | |
| # No insecure compose fallbacks here on purpose: mic_config.erl | |
| # fails closed on the known-insecure default strings, so a | |
| # deployment without strong .env values crashes at boot with an | |
| # explicit error instead of silently running with default creds. | |
| MIC_REALTIME_INTERNAL_TOKEN: ${MIC_REALTIME_INTERNAL_TOKEN} | |
| MIC_REALTIME_SHARED_SECRET: ${MIC_REALTIME_SHARED_SECRET} | |
| MIC_REALTIME_PUBLIC_URL: ${MIC_REALTIME_PUBLIC_URL:-ws://localhost:4001} | |
| MIC_REALTIME_MAX_MSG: 65536 | |
| MIC_REALTIME_RATE_LIMIT: 120 | |
| MIC_REALTIME_PRESENCE_TTL: 90 | |
| REDIS_HOST: redis | |
| REDIS_PORT: 6379 | |
| REDIS_PASSWORD: ${REDIS_PASSWORD:-redis_secret} | |
| ports: | |
| - "4001:4001" | |
| depends_on: | |
| api: | |
| condition: service_started | |
| redis: | |
| condition: service_healthy | |
| networks: | |
| - micprotocol-network | |
| healthcheck: | |
| test: ["CMD", "wget", "-qO-", "http://localhost:4001/healthz"] | |
| interval: 15s | |
| timeout: 5s | |
| retries: 5 | |
| deploy: | |
| resources: | |
| limits: | |
| memory: 1G | |
| cpus: "1.5" | |
| # βββ Next.js Web App βββββββββββββββββββββββββββββββββββββ | |
| web: | |
| build: | |
| context: . | |
| dockerfile: apps/web/Dockerfile | |
| container_name: micprotocol-web | |
| restart: unless-stopped | |
| environment: | |
| NODE_ENV: production | |
| NEXT_PUBLIC_API_URL: ${API_URL:-http://localhost:4000} | |
| NEXT_PUBLIC_MIC_REALTIME_URL: ${MIC_REALTIME_PUBLIC_URL:-ws://localhost:4001} | |
| NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: ${CLERK_PUBLISHABLE_KEY:-pk_test_cGVuZGluZy1tYWNhdy05OC5jbGVyay5hY2NvdW50cy5kZXYk} | |
| CLERK_SECRET_KEY: ${CLERK_SECRET_KEY:-sk_test_cGVuZGluZy1tYWNhdy05OC5jbGVyay5hY2NvdW50cy5kZXYk} | |
| DEV_AUTH_BYPASS_ENABLED: ${DEV_AUTH_BYPASS_ENABLED:-true} | |
| ports: | |
| - "3000:3000" | |
| depends_on: | |
| - api | |
| - mic-realtime | |
| networks: | |
| - micprotocol-network | |
| # βββ Admin Web App βββββββββββββββββββββββββββββββββββββββ | |
| admin: | |
| build: | |
| context: . | |
| dockerfile: apps/admin/Dockerfile | |
| container_name: micprotocol-admin | |
| restart: unless-stopped | |
| environment: | |
| NODE_ENV: production | |
| API_URL: ${API_URL:-http://api:4000} | |
| NEXT_PUBLIC_API_URL: ${API_URL:-http://api:4000} | |
| NEXT_PUBLIC_APP_URL: ${WEB_URL:-http://localhost:3000} | |
| ports: | |
| - "3006:3006" | |
| depends_on: | |
| - api | |
| networks: | |
| - micprotocol-network | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Self-Hosted Integrations (Open-Source SaaS Replacements) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Each service shares the central Postgres + Redis infra above | |
| # (separate DB/schema per service) to keep ops simple. | |
| # Port map: 3001=formbricks 3002=calcom 3003=umami 3004=documenso | |
| # 3005=chatwoot 3006=admin 9000=listmonk | |
| # 9001=minio-s3 9090=minio-console | |
| # βββ Cal.com (Scheduling) ββββββββββββββββββββββββββββββββ | |
| calcom: | |
| image: calcom/cal.com:latest | |
| container_name: micprotocol-calcom | |
| restart: unless-stopped | |
| ports: | |
| - "3002:3000" | |
| environment: | |
| # Bind to all interfaces so other containers can reach Cal.com | |
| HOSTNAME: "0.0.0.0" | |
| # Cal.com requires its own database (Prisma migrations need a clean schema). | |
| DATABASE_URL: postgresql://${POSTGRES_USER:-micprotocol}:${POSTGRES_PASSWORD:-micprotocol_secret}@postgres:5432/calcom?schema=public | |
| DATABASE_DIRECT_URL: postgresql://${POSTGRES_USER:-micprotocol}:${POSTGRES_PASSWORD:-micprotocol_secret}@postgres:5432/calcom?schema=public | |
| NEXTAUTH_SECRET: ${CALCOM_NEXTAUTH_SECRET} | |
| CALENDSO_ENCRYPTION_KEY: ${CALCOM_ENCRYPTION_KEY} | |
| NEXTAUTH_URL: ${CALCOM_URL:-http://localhost:3002} | |
| NEXT_PUBLIC_WEBAPP_URL: ${CALCOM_URL:-http://localhost:3002} | |
| NEXT_PUBLIC_API_V2_URL: ${CALCOM_API_URL:-http://localhost:3002/api/v2} | |
| # Telemetry off for self-hosted | |
| CALCOM_TELEMETRY_DISABLED: "1" | |
| EMAIL_FROM: ${EMAIL_FROM:-noreply@micprotocol.local} | |
| EMAIL_SERVER_HOST: ${SMTP_HOST:-mailhog} | |
| EMAIL_SERVER_PORT: ${SMTP_PORT:-1025} | |
| EMAIL_SERVER_USER: ${SMTP_USER:-mailhog_user} | |
| EMAIL_SERVER_PASSWORD: ${SMTP_PASSWORD:-mailhog_password} | |
| # S3 storage (MinIO) for Cal.com uploads | |
| S3_ACCESS_KEY: ${MINIO_ROOT_USER:-micprotocol_admin} | |
| S3_SECRET_KEY: ${MINIO_ROOT_PASSWORD:-micprotocol_secret} | |
| S3_REGION: us-east-1 | |
| S3_BUCKET: calcom-uploads | |
| S3_ENDPOINT: http://minio:9000 | |
| S3_FORCE_PATH_STYLE: "true" | |
| # Redis for Cal.com v2 API/background jobs | |
| REDIS_URL: redis://:${REDIS_PASSWORD:-redis_secret}@redis:6379 | |
| # Disable paid org features | |
| NEXT_PUBLIC_SINGLE_ORG_SLUG: ${CALCOM_SINGLE_ORG_SLUG:-micprotocol} | |
| ORGANIZATIONS_ENABLED: "0" | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| redis: | |
| condition: service_healthy | |
| healthcheck: | |
| test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"] | |
| interval: 30s | |
| timeout: 10s | |
| retries: 5 | |
| start_period: 40s | |
| networks: | |
| - micprotocol-network | |
| # βββ Listmonk (Newsletter / Email Marketing) βββββββββββββ | |
| listmonk: | |
| image: listmonk/listmonk:latest | |
| container_name: micprotocol-listmonk | |
| restart: unless-stopped | |
| ports: | |
| - "9000:9000" | |
| # Run install + upgrade + serve on first boot. Idempotent. | |
| command: > | |
| sh -c "./listmonk --install --idempotent --yes --config '' && | |
| ./listmonk --upgrade --yes --config '' && | |
| ./listmonk --config ''" | |
| environment: | |
| LISTMONK_app__address: "0.0.0.0:9000" | |
| LISTMONK_db__host: postgres | |
| LISTMONK_db__port: 5432 | |
| LISTMONK_db__user: ${POSTGRES_USER:-micprotocol} | |
| LISTMONK_db__password: ${POSTGRES_PASSWORD:-micprotocol_secret} | |
| LISTMONK_db__database: listmonk | |
| LISTMONK_db__ssl_mode: disable | |
| LISTMONK_db__max_open: 25 | |
| LISTMONK_db__max_idle: 25 | |
| LISTMONK_db__max_lifetime: 300s | |
| # Optional: bootstrap super-admin on first run | |
| LISTMONK_ADMIN_USER: ${LISTMONK_ADMIN_USER:-admin} | |
| LISTMONK_ADMIN_PASSWORD: ${LISTMONK_ADMIN_PASSWORD:-admin_secret} | |
| TZ: Etc/UTC | |
| volumes: | |
| - listmonk_uploads:/listmonk/uploads:rw | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| healthcheck: | |
| test: ["CMD", "wget", "-q", "--spider", "http://localhost:9000/health"] | |
| interval: 30s | |
| timeout: 10s | |
| retries: 5 | |
| start_period: 30s | |
| networks: | |
| - micprotocol-network | |
| # βββ Formbricks (Surveys / Customer Feedback) ββββββββββββ | |
| # v4 architecture: web app + Hub API + Cube (analytics) + migrate job | |
| formbricks-migrate: | |
| image: ghcr.io/formbricks/formbricks:latest | |
| container_name: micprotocol-formbricks-migrate | |
| restart: "no" | |
| entrypoint: ["sh", "-c"] | |
| command: | |
| [ | |
| 'node packages/database/dist/scripts/apply-migrations.js', | |
| ] | |
| environment: | |
| DATABASE_URL: postgresql://${POSTGRES_USER:-micprotocol}:${POSTGRES_PASSWORD:-micprotocol_secret}@postgres:5432/formbricks?schema=public | |
| NEXTAUTH_SECRET: ${FORMBRICKS_NEXTAUTH_SECRET} | |
| ENCRYPTION_KEY: ${FORMBRICKS_ENCRYPTION_KEY} | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| networks: | |
| - micprotocol-network | |
| formbricks: | |
| image: ghcr.io/formbricks/formbricks:latest | |
| container_name: micprotocol-formbricks | |
| restart: unless-stopped | |
| ports: | |
| - "3001:3000" | |
| environment: | |
| # Bind to all interfaces so other containers can reach Formbricks | |
| HOSTNAME: "0.0.0.0" | |
| WEBAPP_URL: ${FORMBRICKS_URL:-http://localhost:3001} | |
| NEXTAUTH_URL: ${FORMBRICKS_URL:-http://localhost:3001} | |
| DATABASE_URL: postgresql://${POSTGRES_USER:-micprotocol}:${POSTGRES_PASSWORD:-micprotocol_secret}@postgres:5432/formbricks?schema=public | |
| NEXTAUTH_SECRET: ${FORMBRICKS_NEXTAUTH_SECRET} | |
| ENCRYPTION_KEY: ${FORMBRICKS_ENCRYPTION_KEY} | |
| CRON_SECRET: ${FORMBRICKS_CRON_SECRET} | |
| REDIS_URL: redis://:${REDIS_PASSWORD:-redis_secret}@redis:6379 | |
| # Skip in-container migrate (handled by formbricks-migrate above) | |
| SKIP_STARTUP_MIGRATION: "true" | |
| # Hub/Cube wiring | |
| HUB_API_URL: http://formbricks-hub:8080 | |
| HUB_API_KEY: ${FORMBRICKS_HUB_API_KEY} | |
| CUBEJS_API_URL: http://formbricks-cube:4000 | |
| CUBEJS_API_SECRET: ${FORMBRICKS_CUBE_API_SECRET} | |
| CUBEJS_JWT_ISSUER: formbricks-web | |
| CUBEJS_JWT_AUDIENCE: formbricks-cube | |
| # Auth defaults (signup disabled without invite) | |
| EMAIL_VERIFICATION_DISABLED: 1 | |
| PASSWORD_RESET_DISABLED: 1 | |
| MAIL_FROM: ${EMAIL_FROM:-noreply@micprotocol.local} | |
| SMTP_HOST: ${SMTP_HOST:-mailhog} | |
| SMTP_PORT: ${SMTP_PORT:-1025} | |
| SMTP_USER: ${SMTP_USER:-mailhog_user} | |
| SMTP_PASSWORD: ${SMTP_PASSWORD:-mailhog_password} | |
| # Telemetry | |
| TELEMETRY_DISABLED: 1 | |
| RATE_LIMITING_DISABLED: 0 | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| redis: | |
| condition: service_healthy | |
| formbricks-migrate: | |
| condition: service_completed_successfully | |
| formbricks-cube: | |
| condition: service_healthy | |
| healthcheck: | |
| test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"] | |
| interval: 30s | |
| timeout: 10s | |
| retries: 5 | |
| start_period: 40s | |
| networks: | |
| - micprotocol-network | |
| formbricks-hub-migrate: | |
| image: ghcr.io/formbricks/hub:latest | |
| container_name: micprotocol-formbricks-hub-migrate | |
| restart: "no" | |
| entrypoint: ["sh", "-c"] | |
| command: | |
| [ | |
| '/usr/local/bin/goose -dir /app/migrations postgres "$$DATABASE_URL" up && /usr/local/bin/river migrate-up --database-url "$$DATABASE_URL"', | |
| ] | |
| environment: | |
| DATABASE_URL: postgresql://${POSTGRES_USER:-micprotocol}:${POSTGRES_PASSWORD:-micprotocol_secret}@postgres:5432/formbricks?schema=public | |
| depends_on: | |
| formbricks-migrate: | |
| condition: service_completed_successfully | |
| networks: | |
| - micprotocol-network | |
| formbricks-hub: | |
| image: ghcr.io/formbricks/hub:latest | |
| container_name: micprotocol-formbricks-hub | |
| restart: unless-stopped | |
| environment: | |
| API_KEY: ${FORMBRICKS_HUB_API_KEY} | |
| DATABASE_URL: postgresql://${POSTGRES_USER:-micprotocol}:${POSTGRES_PASSWORD:-micprotocol_secret}@postgres:5432/formbricks?schema=public | |
| depends_on: | |
| formbricks-hub-migrate: | |
| condition: service_completed_successfully | |
| postgres: | |
| condition: service_healthy | |
| healthcheck: | |
| test: ["CMD", "curl", "-f", "http://localhost:8080/health"] | |
| interval: 30s | |
| timeout: 10s | |
| retries: 5 | |
| start_period: 30s | |
| networks: | |
| - micprotocol-network | |
| formbricks-cube: | |
| image: cubejs/cube:v1.6.6 | |
| container_name: micprotocol-formbricks-cube | |
| restart: unless-stopped | |
| command: ["sh", "-c", "exec cubejs server"] | |
| environment: | |
| CUBEJS_DB_TYPE: postgres | |
| CUBEJS_DB_HOST: postgres | |
| CUBEJS_DB_NAME: formbricks | |
| CUBEJS_DB_USER: ${POSTGRES_USER:-micprotocol} | |
| CUBEJS_DB_PASS: ${POSTGRES_PASSWORD:-micprotocol_secret} | |
| CUBEJS_DB_PORT: 5432 | |
| CUBEJS_API_SECRET: ${FORMBRICKS_CUBE_API_SECRET} | |
| CUBEJS_JWT_ISSUER: formbricks-web | |
| CUBEJS_JWT_AUDIENCE: formbricks-cube | |
| CUBEJS_DEFAULT_API_SCOPES: meta,data | |
| CUBEJS_CACHE_AND_QUEUE_DRIVER: memory | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| healthcheck: | |
| test: ["CMD", "node", "-e", "require('http').get('http://127.0.0.1:4000/readyz',(r)=>{r.resume();process.exit(r.statusCode===200?0:1)}).on('error',()=>process.exit(1))"] | |
| interval: 10s | |
| timeout: 5s | |
| retries: 12 | |
| start_period: 30s | |
| networks: | |
| - micprotocol-network | |
| # βββ Documenso (Document e-signing) ββββββββββββββββββββββ | |
| # Requires a signing cert. Generate via instructions in .env.example | |
| documenso: | |
| image: documenso/documenso:latest | |
| container_name: micprotocol-documenso | |
| restart: unless-stopped | |
| ports: | |
| - "3004:3000" | |
| environment: | |
| # Bind to all interfaces so other containers can reach Documenso | |
| HOSTNAME: "0.0.0.0" | |
| PORT: 3000 | |
| NEXTAUTH_SECRET: ${DOCUMENSO_NEXTAUTH_SECRET} | |
| NEXT_PRIVATE_ENCRYPTION_KEY: ${DOCUMENSO_ENCRYPTION_KEY} | |
| NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY: ${DOCUMENSO_ENCRYPTION_SECONDARY_KEY} | |
| NEXT_PUBLIC_WEBAPP_URL: ${DOCUMENSO_URL:-http://localhost:3004} | |
| NEXT_PRIVATE_INTERNAL_WEBAPP_URL: http://documenso:3000 | |
| NEXT_PRIVATE_DATABASE_URL: postgresql://${POSTGRES_USER:-micprotocol}:${POSTGRES_PASSWORD:-micprotocol_secret}@postgres:5432/documenso?schema=public | |
| NEXT_PRIVATE_DIRECT_DATABASE_URL: postgresql://${POSTGRES_USER:-micprotocol}:${POSTGRES_PASSWORD:-micprotocol_secret}@postgres:5432/documenso?schema=public | |
| # Uploads via MinIO (S3-compatible) | |
| NEXT_PUBLIC_UPLOAD_TRANSPORT: s3 | |
| NEXT_PRIVATE_UPLOAD_ENDPOINT: http://minio:9000 | |
| NEXT_PRIVATE_UPLOAD_FORCE_PATH_STYLE: "true" | |
| NEXT_PRIVATE_UPLOAD_REGION: us-east-1 | |
| NEXT_PRIVATE_UPLOAD_BUCKET: documenso-uploads | |
| NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID: ${MINIO_ROOT_USER:-micprotocol_admin} | |
| NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD:-micprotocol_secret} | |
| # SMTP | |
| NEXT_PRIVATE_SMTP_TRANSPORT: smtp | |
| NEXT_PRIVATE_SMTP_HOST: ${SMTP_HOST:-mailhog} | |
| NEXT_PRIVATE_SMTP_PORT: ${SMTP_PORT:-1025} | |
| NEXT_PRIVATE_SMTP_SECURE: "false" | |
| NEXT_PRIVATE_SMTP_FROM_NAME: MicProtocol | |
| NEXT_PRIVATE_SMTP_FROM_ADDRESS: ${EMAIL_FROM:-noreply@micprotocol.local} | |
| # Signing cert (mounted read-only below, generated by host per .env.example) | |
| NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH: /opt/documenso/cert.p12 | |
| NEXT_PRIVATE_SIGNING_PASSPHRASE: ${DOCUMENSO_SIGNING_PASSPHRASE} | |
| # Disable paid signup gates for self-hosted | |
| NEXT_PUBLIC_DISABLE_SIGNIN: "false" | |
| NEXT_PUBLIC_DISABLE_SIGNUP: "false" | |
| volumes: | |
| - ./scripts/documenso-cert:/opt/documenso/cert:ro | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| networks: | |
| - micprotocol-network | |
| # βββ Chatwoot (Customer Support / Live Chat) ββββββββββββ | |
| # Rails + Sidekiq workers, palette requested separately to keep | |
| # things simple by default. | |
| chatwoot-web: | |
| image: chatwoot/chatwoot:latest | |
| container_name: micprotocol-chatwoot-web | |
| restart: unless-stopped | |
| ports: | |
| - "3005:3000" | |
| entrypoint: docker/entrypoints/rails.sh | |
| command: ["bundle", "exec", "rails", "s", "-p", "3000", "-b", "0.0.0.0"] | |
| environment: | |
| NODE_ENV: production | |
| RAILS_ENV: production | |
| INSTALLATION_ENV: docker | |
| SECRET_KEY_BASE: ${CHATWOOT_SECRET_KEY_BASE} | |
| RAILS_LOG_TO_STDOUT: "true" | |
| # Database β chatwoot needs pgvector; see init-databases.sql | |
| POSTGRES_HOST: postgres | |
| POSTGRES_PORT: 5432 | |
| POSTGRES_DATABASE: chatwoot | |
| POSTGRES_USERNAME: ${POSTGRES_USER:-micprotocol} | |
| POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-micprotocol_secret} | |
| DATABASE_URL: postgresql://${POSTGRES_USER:-micprotocol}:${POSTGRES_PASSWORD:-micprotocol_secret}@postgres:5432/chatwoot?sslmode=disable | |
| # Redis (shared instance, namespaced by Chatwoot internally) | |
| REDIS_URL: redis://:${REDIS_PASSWORD:-redis_secret}@redis:6379 | |
| REDIS_PASSWORD: ${REDIS_PASSWORD:-redis_secret} | |
| REDIS_SIDEKIQ_URL: redis://:${REDIS_PASSWORD:-redis_secret}@redis:6379 | |
| # Frontend URL | |
| FRONTEND_URL: ${CHATWOOT_URL:-http://localhost:3005} | |
| # SMTP for outbound mail | |
| SMTP_ADDRESS: ${SMTP_HOST:-mailhog} | |
| SMTP_PORT: ${SMTP_PORT:-1025} | |
| SMTP_USERNAME: ${SMTP_USER:-} | |
| SMTP_PASSWORD: ${SMTP_PASSWORD:-} | |
| SMTP_DOMAIN: ${SMTP_DOMAIN:-micprotocol.local} | |
| MAILER_SENDER_EMAIL: ${EMAIL_FROM:-Chatwoot <support@micprotocol.local>} | |
| # Storage | |
| ACTIVE_STORAGE_SERVICE: local | |
| RAILS_STORAGE_LOCATION: /app/storage | |
| # Disable dev-mode features | |
| ENABLE_ACCOUNT_GAME: "false" | |
| USE_INBOUND_EMAIL_SERVICE: "false" | |
| volumes: | |
| - chatwoot_storage:/app/storage | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| redis: | |
| condition: service_healthy | |
| healthcheck: | |
| test: ["CMD", "curl", "-f", "http://localhost:3000/health"] | |
| interval: 30s | |
| timeout: 10s | |
| retries: 5 | |
| start_period: 60s | |
| networks: | |
| - micprotocol-network | |
| chatwoot-worker: | |
| image: chatwoot/chatwoot:latest | |
| container_name: micprotocol-chatwoot-worker | |
| restart: unless-stopped | |
| command: ["bundle", "exec", "sidekiq", "-C", "config/sidekiq.yml"] | |
| environment: | |
| NODE_ENV: production | |
| RAILS_ENV: production | |
| INSTALLATION_ENV: docker | |
| SECRET_KEY_BASE: ${CHATWOOT_SECRET_KEY_BASE} | |
| RAILS_LOG_TO_STDOUT: "true" | |
| POSTGRES_HOST: postgres | |
| POSTGRES_PORT: 5432 | |
| POSTGRES_DATABASE: chatwoot | |
| POSTGRES_USERNAME: ${POSTGRES_USER:-micprotocol} | |
| POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-micprotocol_secret} | |
| DATABASE_URL: postgresql://${POSTGRES_USER:-micprotocol}:${POSTGRES_PASSWORD:-micprotocol_secret}@postgres:5432/chatwoot?sslmode=disable | |
| REDIS_URL: redis://:${REDIS_PASSWORD:-redis_secret}@redis:6379 | |
| REDIS_PASSWORD: ${REDIS_PASSWORD:-redis_secret} | |
| REDIS_SIDEKIQ_URL: redis://:${REDIS_PASSWORD:-redis_secret}@redis:6379 | |
| FRONTEND_URL: ${CHATWOOT_URL:-http://localhost:3005} | |
| SMTP_ADDRESS: ${SMTP_HOST:-mailhog} | |
| SMTP_PORT: ${SMTP_PORT:-1025} | |
| SMTP_USERNAME: ${SMTP_USER:-} | |
| SMTP_PASSWORD: ${SMTP_PASSWORD:-} | |
| SMTP_DOMAIN: ${SMTP_DOMAIN:-micprotocol.local} | |
| MAILER_SENDER_EMAIL: ${EMAIL_FROM:-Chatwoot <support@micprotocol.local>} | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| redis: | |
| condition: service_healthy | |
| healthcheck: | |
| test: ["CMD", "bundle", "exec", "sidekiq", "health"] | |
| interval: 30s | |
| timeout: 10s | |
| retries: 5 | |
| start_period: 60s | |
| networks: | |
| - micprotocol-network | |
| # βββ Pretix (Self-Hosted Ticketing & Event Registration) βββββ | |
| # Open-source ticketing platform. Port 8000 inside Docker network. | |
| # Pretix uses its own Postgres database + Redis + a separate pretixworker. | |
| pretix: | |
| image: pretix/pretix:latest | |
| container_name: micprotocol-pretix | |
| restart: unless-stopped | |
| ports: | |
| - "8000:8000" | |
| environment: | |
| PRETIX_DB_BACKEND: postgres | |
| PRETIX_DB_NAME: pretix | |
| PRETIX_DB_USER: ${POSTGRES_USER:-micprotocol} | |
| PRETIX_DB_PASSWORD: ${POSTGRES_PASSWORD:-micprotocol_secret} | |
| PRETIX_DB_HOST: postgres | |
| PRETIX_DB_PORT: 5432 | |
| PRETIX_URL: ${PRETIX_URL:-http://localhost:8000} | |
| PRETIX_ADMIN_EMAIL: ${PRETIX_ADMIN_EMAIL:-admin@micprotocol.local} | |
| PRETIX_ADMIN_PASSWORD: ${PRETIX_ADMIN_PASSWORD:-admin_secret} | |
| PRETIX_ADMIN_NAME: MicProtocol Admin | |
| PRETIX_INSTANCE_NAME: MicProtocol Ticketing | |
| PRETIX_INSTANCE_SLUG: micprotocol | |
| PRETIX_SECRET: ${PRETIX_SECRET} | |
| PRETIX_EMAIL_BACKEND: django.core.mail.backends.console.EmailBackend | |
| # Pretix needs Redis for caching | |
| PRETIX_REDIS_URL: redis://:${REDIS_PASSWORD:-redis_secret}@redis:6379 | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| redis: | |
| condition: service_healthy | |
| networks: | |
| - micprotocol-network | |
| pretixworker: | |
| image: pretix/pretix:latest | |
| container_name: micprotocol-pretixworker | |
| restart: unless-stopped | |
| command: pretixworker | |
| environment: | |
| PRETIX_DB_BACKEND: postgres | |
| PRETIX_DB_NAME: pretix | |
| PRETIX_DB_USER: ${POSTGRES_USER:-micprotocol} | |
| PRETIX_DB_PASSWORD: ${POSTGRES_PASSWORD:-micprotocol_secret} | |
| PRETIX_DB_HOST: postgres | |
| PRETIX_DB_PORT: 5432 | |
| PRETIX_URL: ${PRETIX_URL:-http://localhost:8000} | |
| PRETIX_SECRET: ${PRETIX_SECRET} | |
| PRETIX_REDIS_URL: redis://:${REDIS_PASSWORD:-redis_secret}@redis:6379 | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| redis: | |
| condition: service_healthy | |
| pretix: | |
| condition: service_healthy | |
| networks: | |
| - micprotocol-network | |
| # βββ MinIO (S3-compatible storage for all integrations) ββ | |
| minio: | |
| image: minio/minio:latest | |
| container_name: micprotocol-minio | |
| restart: unless-stopped | |
| ports: | |
| - "9001:9000" | |
| - "9090:9090" | |
| environment: | |
| MINIO_ROOT_USER: ${MINIO_ROOT_USER:-micprotocol_admin} | |
| MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-micprotocol_secret} | |
| command: server /data --console-address ":9090" | |
| volumes: | |
| - minio_data:/data | |
| networks: | |
| - micprotocol-network | |
| # One-shot bucket creator for all S3 consumers | |
| minio-createbuckets: | |
| image: minio/mc:latest | |
| container_name: micprotocol-minio-mc | |
| depends_on: | |
| - minio | |
| restart: "no" | |
| entrypoint: > | |
| /bin/sh -c " | |
| /usr/bin/mc alias set myminio http://minio:9000 ${MINIO_ROOT_USER:-micprotocol_admin} ${MINIO_ROOT_PASSWORD:-micprotocol_secret}; | |
| /usr/bin/mc mb myminio/micprotocol-storage --ignore-existing; | |
| /usr/bin/mc mb myminio/calcom-uploads --ignore-existing; | |
| /usr/bin/mc mb myminio/documenso-uploads --ignore-existing; | |
| /usr/bin/mc mb myminio/formbricks-uploads --ignore-existing; | |
| /usr/bin/mc anonymous set public myminio/micprotocol-storage; | |
| exit 0; | |
| " | |
| networks: | |
| - micprotocol-network | |
| # βββ Umami (Self-hosted web analytics) βββββββββββββββββββ | |
| umami: | |
| image: ghcr.io/umami-software/umami:postgresql-latest | |
| container_name: micprotocol-umami | |
| restart: unless-stopped | |
| ports: | |
| - "3003:3000" | |
| environment: | |
| # Bind to all interfaces so other containers can reach Umami | |
| HOSTNAME: "0.0.0.0" | |
| DATABASE_URL: postgresql://${POSTGRES_USER:-micprotocol}:${POSTGRES_PASSWORD:-micprotocol_secret}@postgres:5432/umami?schema=public | |
| DATABASE_TYPE: postgresql | |
| APP_SECRET: ${UMAMI_APP_SECRET} | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| networks: | |
| - micprotocol-network | |
| # βββ LiveKit (WebRTC SFU for recording studio) ββββββββββ | |
| # Provides real-time multi-participant audio rooms. | |
| # Ports: 7880 (HTTP), 7881 (TCP), 7882 (UDP), 7883 (TURN/TLS) | |
| livekit: | |
| image: livekit/livekit-server:latest | |
| container_name: micprotocol-livekit | |
| restart: unless-stopped | |
| ports: | |
| - "7880:7880" | |
| - "7881:7881" | |
| - "7882:7882/udp" | |
| command: | |
| - --config | |
| - /etc/livekit.yaml | |
| volumes: | |
| - ./services/livekit/livekit.yaml:/etc/livekit.yaml:ro | |
| networks: | |
| - micprotocol-network | |
| # βββ coturn (TURN server for LiveKit NAT traversal) βββββββ | |
| # Provides TURN/STUN relay for WebRTC participants behind symmetric NAT. | |
| # LiveKit autodiscords TURN via the coturn REST API / livekit config. | |
| coturn: | |
| image: coturn/coturn:4.6.2 | |
| container_name: micprotocol-coturn | |
| restart: unless-stopped | |
| command: > | |
| sh -c " | |
| turnserver -v | |
| --listening-port=3478 | |
| --tls-listening-port=5349 | |
| --min-port=49152 --max-port=65535 | |
| --use-auth-secret | |
| --static-auth-secret=${COTURN_SECRET:-coturn_secret} | |
| --realm=${ROOT_DOMAIN:-localhost} | |
| --no-cli | |
| --no-stdout-log | |
| --syslog | |
| " | |
| environment: | |
| COTURN_SECRET: ${COTURN_SECRET:-coturn_secret} | |
| ROOT_DOMAIN: ${ROOT_DOMAIN:-localhost} | |
| ports: | |
| - "3478:3478/tcp" | |
| - "3478:3478/udp" | |
| - "5349:5349/tcp" | |
| - "5349:5349/udp" | |
| - "49152-65535:49152-65535/udp" | |
| networks: | |
| - micprotocol-network | |
| # βββ Mailhog (Local SMTP catch-all for all services) βββββ | |
| # Replaces paid SMTP services in dev. Swagger UI at :8025. | |
| # In production, point SMTP_HOST/PORT to your real relay. | |
| mailhog: | |
| image: mailhog/mailhog:latest | |
| container_name: micprotocol-mailhog | |
| restart: unless-stopped | |
| ports: | |
| - "1025:1025" | |
| - "8025:8025" | |
| networks: | |
| - micprotocol-network | |
| # βββ Volumes βββββββββββββββββββββββββββββββββββββββββββββββ | |
| volumes: | |
| postgres_data: | |
| driver: local | |
| redis_data: | |
| driver: local | |
| meilisearch_data: | |
| driver: local | |
| minio_data: | |
| driver: local | |
| listmonk_uploads: | |
| driver: local | |
| chatwoot_storage: | |
| driver: local | |
| # βββ Networks ββββββββββββββββββββββββββββββββββββββββββββββ | |
| networks: | |
| micprotocol-network: | |
| driver: bridge | |