services: # PostgreSQL must load the vector library so Hub (and Formbricks) can use the pgvector extension. postgres: image: pgvector/pgvector:pg18 volumes: - postgres:/var/lib/postgresql environment: - POSTGRES_DB=postgres - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres ports: - 5432:5432 command: > postgres -c shared_preload_libraries=vector healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -d postgres || exit 1"] interval: 5s timeout: 3s retries: 30 start_period: 10s mailhog: image: arjenz/mailhog ports: - 8025:8025 - 1025:1025 valkey: image: valkey/valkey@sha256:12ba4f45a7c3e1d0f076acd616cb230834e75a77e8516dde382720af32832d6d command: "valkey-server --maxmemory-policy noeviction" ports: - 6379:6379 volumes: - valkey-data:/data minio: image: minio/minio:RELEASE.2025-09-07T16-13-09Z command: server /data --console-address ":9001" environment: - MINIO_ROOT_USER=devminio - MINIO_ROOT_PASSWORD=devminio123 ports: - "9000:9000" # S3 API direct access - "9001:9001" # Web console volumes: - minio-data:/data # Run Hub DB migrations (goose + river) before the API starts. Idempotent; runs on every compose up. hub-migrate: image: ghcr.io/formbricks/hub:latest restart: "no" entrypoint: ["sh", "-c"] command: [ 'if [ -x /usr/local/bin/goose ] && [ -x /usr/local/bin/river ]; then /usr/local/bin/goose -dir /app/migrations postgres "$$DATABASE_URL" up && /usr/local/bin/river migrate-up --database-url "$$DATABASE_URL"; else echo ''Migration tools (goose/river) not in image.''; exit 1; fi', ] environment: DATABASE_URL: postgresql://postgres:postgres@postgres:5432/postgres?sslmode=disable depends_on: postgres: condition: service_healthy # Formbricks Hub API (ghcr.io/formbricks/hub). Shares the same Postgres database as Formbricks by default. hub: image: ghcr.io/formbricks/hub:latest depends_on: hub-migrate: condition: service_completed_successfully ports: - "8080:8080" environment: API_KEY: ${HUB_API_KEY:-dev-api-key} DATABASE_URL: postgresql://postgres:postgres@postgres:5432/postgres?sslmode=disable # Explicit Postgres env so migrations and any libpq fallback use the service host, not localhost PGHOST: postgres PGPORT: "5432" PGUSER: postgres PGPASSWORD: postgres PGDATABASE: postgres PGSSLMODE: disable cube: image: cubejs/cube:v1.6.6 env_file: - apps/web/.env ports: - 4000:4000 - 4001:4001 # Cube Playground UI (dev only) environment: CUBEJS_DB_TYPE: postgres CUBEJS_DB_HOST: ${CUBEJS_DB_HOST:-formbricks_hub_postgres} CUBEJS_DB_NAME: ${CUBEJS_DB_NAME:-hub} CUBEJS_DB_USER: ${CUBEJS_DB_USER:-formbricks} CUBEJS_DB_PASS: ${CUBEJS_DB_PASS:-formbricks_dev} CUBEJS_DB_PORT: ${CUBEJS_DB_PORT:-5432} CUBEJS_DEV_MODE: "true" CUBEJS_API_SECRET: ${CUBEJS_API_SECRET} CUBEJS_CACHE_AND_QUEUE_DRIVER: memory volumes: - ./cube/cube.js:/cube/conf/cube.js - ./cube/schema:/cube/conf/model restart: on-failure networks: - default - hub networks: hub: external: true name: superset_formbricks_hub volumes: postgres: driver: local valkey-data: driver: local minio-data: driver: local