Spaces:
Sleeping
Sleeping
| version: "3.6" | |
| services: | |
| traefik: | |
| image: "traefik:v2.10.4" | |
| container_name: "traefik" | |
| command: | |
| - "--log.level=ERROR" | |
| - "--providers.docker=true" | |
| - "--providers.docker.exposedByDefault=false" | |
| - "--entrypoints.web.address=:80" | |
| - "--entrypoints.websecure.address=:443" | |
| # Let's Encrypt Resolver Configuration | |
| - "--certificatesresolvers.le.acme.email=${LETSENCRYPT_EMAIL:-admin@example.com}" # Placeholder for user's email | |
| - "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json" | |
| - "--certificatesresolvers.le.acme.httpchallenge=true" | |
| - "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web" | |
| # Global HTTP to HTTPS redirection (optional, can also be per-router) | |
| # - "--entrypoints.web.http.redirections.entrypoint.to=websecure" | |
| # - "--entrypoints.web.http.redirections.entrypoint.scheme=https" | |
| labels: | |
| - traefik.http.middlewares.strip-traefik.stripprefix.prefixes=/v1/traefik | |
| - traefik.http.routers.traefik.rule=Host(`${HOST_NAME}`) && PathPrefix(`/v1/traefik`) || Host(`localhost`) && PathPrefix(`/v1/traefik`) | |
| - traefik.http.routers.traefik.entrypoints=web # Traefik dashboard itself can remain on HTTP for simplicity if only accessed locally or via tunnel | |
| - traefik.http.routers.traefik.middlewares=strip-traefik@docker,traefik-auth@docker # Added auth to traefik dashboard | |
| - traefik.http.routers.traefik.service=api@internal | |
| - "traefik.http.middlewares.traefik-auth.basicauth.users=${TRAEFIK_USER:-admin}:${TRAEFIK_PASSWORD:-password}" # Renamed middleware for clarity | |
| # Middleware for HTTP to HTTPS redirection | |
| - "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https" | |
| - "traefik.http.middlewares.https-redirect.redirectscheme.permanent=true" | |
| ports: | |
| - "80:80" | |
| - "443:443" | |
| - "9090:8080" # Traefik API/Dashboard port (if enabled and needed) | |
| volumes: | |
| - ./letsencrypt:/letsencrypt | |
| - "/var/run/docker.sock:/var/run/docker.sock:ro" | |
| whoami: # Test service, useful for debugging Traefik rules | |
| image: "traefik/whoami" | |
| container_name: "whoami" | |
| expose: | |
| - 80 # whoami listens on port 80 by default | |
| labels: | |
| - "traefik.enable=true" | |
| # HTTP router for whoami (for testing) | |
| - "traefik.http.routers.whoami-http.rule=Host(`${HOST_NAME:-localhost}`) && PathPrefix(`/v1/whoami-http`)" | |
| - "traefik.http.routers.whoami-http.entrypoints=web" | |
| - "traefik.http.services.whoami.loadbalancer.server.port=80" # whoami default port | |
| # HTTPS router for whoami (for testing HTTPS setup) | |
| - "traefik.http.routers.whoami-https.rule=Host(`${HOST_NAME:-localhost}`) && PathPrefix(`/v1/whoami`)" | |
| - "traefik.http.routers.whoami-https.entrypoints=websecure" | |
| - "traefik.http.routers.whoami-https.tls=true" | |
| - "traefik.http.routers.whoami-https.tls.certresolver=le" | |
| - "traefik.http.routers.whoami-https.service=whoami" # Use the same service definition | |
| postgres: | |
| image: postgres:13-alpine | |
| restart: always | |
| volumes: | |
| - ./postgres/data:/var/lib/postgresql/data | |
| - ./initdb.d:/docker-entrypoint-initdb.d:ro | |
| environment: | |
| POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-secretpgpassword} | |
| POSTGRES_USERNAME: ${POSTGRES_USERNAME:-postgres} | |
| healthcheck: | |
| test: | |
| ["CMD", "pg_isready", "-U", "${POSTGRES_USERNAME}", "-d", "postgres"] | |
| interval: 5s | |
| timeout: 5s | |
| retries: 5 | |
| ports: | |
| - "5432:5432" | |
| supertokens: | |
| image: registry.supertokens.io/supertokens/supertokens-postgresql:6.0 | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| expose: | |
| - 3567 | |
| environment: | |
| POSTGRESQL_CONNECTION_URI: ${SUPERTOKENS_POSTGRESQL_CONNECTION_URI:-postgresql://postgres:secretpgpassword@postgres:5432/postgres} | |
| POSTGRESQL_TABLE_NAMES_PREFIX: Supertokens | |
| restart: unless-stopped | |
| labels: | |
| - "traefik.enable=true" | |
| - "traefik.http.middlewares.strip-auth.stripprefix.prefixes=/v1/auth" | |
| # HTTP router for auth (redirects to HTTPS) | |
| - "traefik.http.routers.auth-http.rule=Host(`${HOST_NAME:-localhost}`) && PathPrefix(`/v1/auth`)" | |
| - "traefik.http.routers.auth-http.entrypoints=web" | |
| - "traefik.http.routers.auth-http.middlewares=strip-auth@docker,https-redirect@docker" | |
| # HTTPS router for auth | |
| - "traefik.http.routers.auth-https.rule=Host(`${HOST_NAME:-localhost}`) && PathPrefix(`/v1/auth`)" | |
| - "traefik.http.routers.auth-https.entrypoints=websecure" | |
| - "traefik.http.routers.auth-https.tls=true" | |
| - "traefik.http.routers.auth-https.tls.certresolver=le" | |
| - "traefik.http.routers.auth-https.middlewares=strip-auth@docker" | |
| - "traefik.http.routers.auth-https.service=auth-service" # Explicit service name | |
| - "traefik.http.services.auth-service.loadbalancer.server.port=3567" | |
| healthcheck: | |
| test: ["CMD", "curl", "-f", "http://localhost:3567/hello"] | |
| interval: 30s | |
| timeout: 10s | |
| retries: 3 | |
| start_period: 30s | |
| postgraphile: | |
| image: graphile/postgraphile:4 # Using latest V4, V5 is still in beta | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| restart: always | |
| ports: | |
| - "5000:5000" # Default PostGraphile port | |
| environment: | |
| DATABASE_URL: postgres://${POSTGRES_USERNAME}:${POSTGRES_PASSWORD:-secretpgpassword}@postgres:5432/postgres | |
| PGRAPHILE_WATCH_PG: "true" # Enable watch mode for schema changes | |
| PGRAPHILE_JWT_SECRET: ${POSTGRAPHILE_JWT_SECRET:-secretjwtsecret} # JWT secret for PostGraphile | |
| PGRAPHILE_JWT_PG_ROLE: public # Default role if not authenticated, or specify a dedicated one | |
| PGRAPHILE_PG_DEFAULT_ROLE: public # Role to use for unauthenticated requests | |
| # PostGraphile doesn't have a direct admin secret concept for API access. Access control is via PG roles. | |
| # For enhanced security, consider using a dedicated read-only role for PostGraphile unless mutations are needed. | |
| # PGRAPHILE_OWNER_CONNECTION_STRING: postgres://${POSTGRES_USERNAME}:${POSTGRES_PASSWORD:-secretpgpassword}@postgres:5432/postgres # For schema watching and migrations if needed with a more privileged user | |
| PGRAPHILE_ENABLE_GRAPHIQL: "true" | |
| # Add any other necessary PostGraphile environment variables here | |
| # e.g., PGRAPHILE_SCHEMA_NAMES: public,app_public # Specify schemas to expose | |
| # PGRAPHILE_APPEND_PLUGINS: @graphile-contrib/pg-simplify-inflector,@graphile/pg-pubsub | |
| # PGRAPHILE_SIMPLE_COLLECTIONS: omit # or 'both' or 'only' | |
| # PGRAPHILE_ENHANCE_GRAPHIQL: 'true' | |
| # PGRAPHILE_ALLOW_EXPLAIN: 'true' # For debugging, be cautious in production | |
| healthcheck: | |
| test: [ | |
| "CMD-SHELL", | |
| "curl -f http://localhost:5000/graphql?query={__typename} || exit 1", | |
| ] # Basic healthcheck query | |
| interval: 30s | |
| timeout: 10s | |
| retries: 3 | |
| start_period: 30s | |
| functions: | |
| build: ../../frontend-nextjs/project/functions | |
| container_name: "functions" | |
| depends_on: | |
| - minio | |
| - zookeeper | |
| - kafka1 | |
| - optaplanner | |
| - postgres | |
| - postgraphile # Changed from graphql-engine | |
| - redis # Replaced mongo with redis | |
| environment: | |
| BASIC_AUTH: ${BASIC_AUTH:-false} | |
| FUNCTION_SERVER_URL: ${FUNCTION_SERVER_URL:-http://functions:3000} | |
| OPENAI_API_KEY: ${OPENAI_API_KEY:-sk-default-openai-key} | |
| GOOGLE_CLIENT_ID_ANDROID: ${GOOGLE_CLIENT_ID_ANDROID:-default_android_client_id} | |
| GOOGLE_CLIENT_ID_IOS: ${GOOGLE_CLIENT_ID_IOS:-default_ios_client_id} | |
| GOOGLE_CLIENT_ID_WEB: ${GOOGLE_CLIENT_ID_WEB:-default_web_client_id} | |
| GOOGLE_CLIENT_ID_ATOMIC_WEB: ${GOOGLE_CLIENT_ID_ATOMIC_WEB:-} | |
| GOOGLE_CLIENT_SECRET_ATOMIC_WEB: ${GOOGLE_CLIENT_SECRET_ATOMIC_WEB:-} | |
| # PostGraphile doesn't use admin secrets, access control is via PG roles | |
| POSTGRAPHILE_GRAPHQL_URL: http://postgraphile:5000/graphql # New URL for PostGraphile | |
| # Not applicable for PostGraphile | |
| GOOGLE_CLIENT_SECRET_WEB: ${GOOGLE_CLIENT_SECRET_WEB:-default_web_secret} | |
| EMAIL: ${EMAIL:-admin@example.com} | |
| # Base URL for the Python API service (running in python-agent) | |
| # NOTE: python-agent service removed - duplicate functionality exists in backend/integrations/ | |
| # PYTHON_API_SERVICE_BASE_URL: ${PYTHON_API_SERVICE_BASE_URL:-http://python-agent:5000} | |
| DOMAIN: ${DOMAIN:-localhost} | |
| S3_ENDPOINT: http://minio:8484 | |
| S3_BUCKET: nhost | |
| S3_ACCESS_KEY: ${STORAGE_ACCESS_KEY:-minioadmin} | |
| S3_SECRET_KEY: ${STORAGE_SECRET_KEY:-minioadmin} | |
| KAFKA_USERNAME: ${KAFKA_USERNAME:-kafka-user} | |
| KAFKA_PASSWORD: ${KAFKA_PASSWORD:-kafka-password} | |
| HOST_IP: ${HOST_IP:-127.0.0.1} | |
| ZOOM_PASS_KEY: ${ZOOM_PASS_KEY:-default_zoom_pass_key} | |
| ZOOM_CLIENT_ID: ${ZOOM_CLIENT_ID:-default_zoom_client_id} | |
| ZOOM_SALT_FOR_PASS: ${ZOOM_SALT_FOR_PASS:-default_salt} | |
| ZOOM_IV_FOR_PASS: ${ZOOM_IV_FOR_PASS:-default_iv} | |
| OPTAPLANNER_URL: http://optaplanner:8081 | |
| OPTAPLANNER_USERNAME: ${OPTAPLANNER_USERNAME:-admin} | |
| OPTAPLANNER_PASSWORD: ${OPTAPLANNER_PASSWORD:-adminpassword} | |
| OPTAPLAN_ADMIN_CALLBACK_URL: http://functions:3000/post-process-calendar/onPostOptaCal/on-opta-plan-post-process-calendar-admin | |
| GOOGLE_CALENDAR_WEBHOOK_URL: https://${HOST_NAME:-localhost}/v1/functions/google-calendar-sync/googleCalendarWebhook/google-calendar-webhook-public | |
| GOOGLE_PEOPLE_SYNC_ADMIN_URL: https://${HOST_NAME:-localhost}/v1/functions/google-calendar-sync/googlePeopleSync/google-contact-sync-admin | |
| OPTAPLANNER_DURATION: ${OPTAPLANNER_DURATION:-60} | |
| OPTAPLANNER_SHORT_DURATION: ${OPTAPLANNER_SHORT_DURATION:-30} | |
| APP_CLIENT_URL: ${APP_CLIENT_URL:-http://localhost:3000} | |
| labels: | |
| - "traefik.enable=true" | |
| - "traefik.http.middlewares.strip-functions.stripprefix.prefixes=/v1/functions" | |
| # HTTP router for functions (redirects to HTTPS) | |
| - "traefik.http.routers.functions-http.rule=Host(`${HOST_NAME:-localhost}`) && PathPrefix(`/v1/functions/`)" | |
| - "traefik.http.routers.functions-http.entrypoints=web" | |
| - "traefik.http.routers.functions-http.middlewares=strip-functions@docker,https-redirect@docker" | |
| # HTTPS router for functions | |
| - "traefik.http.routers.functions-https.rule=Host(`${HOST_NAME:-localhost}`) && PathPrefix(`/v1/functions/`)" | |
| - "traefik.http.routers.functions-https.entrypoints=websecure" | |
| - "traefik.http.routers.functions-https.tls=true" | |
| - "traefik.http.routers.functions-https.tls.certresolver=le" | |
| - "traefik.http.routers.functions-https.middlewares=strip-functions@docker" | |
| - "traefik.http.routers.functions-https.service=functions-service" # Explicit service name | |
| - "traefik.http.services.functions-service.loadbalancer.server.port=3000" | |
| healthcheck: | |
| test: ["CMD", "curl", "-f", "http://localhost:3000/healthz"] # Assuming a /healthz endpoint exists or will be added | |
| interval: 30s | |
| timeout: 10s | |
| retries: 3 | |
| start_period: 60s # Give functions a bit longer to start | |
| restart: always | |
| expose: | |
| - 3000 | |
| ports: | |
| - 3030:3030 | |
| volumes: | |
| - ../../frontend-nextjs/project/functions:/app | |
| - functions_node_modules:/app/node_modules | |
| - ../../frontend-nextjs/project/functions/logs:/app/logs | |
| minio: | |
| image: minio/minio:RELEASE.2021-09-24T00-24-24Z | |
| entrypoint: sh | |
| command: -c 'mkdir -p /data/nhost && /opt/bin/minio server --console-address :9001 --address :8484 /data' | |
| environment: | |
| MINIO_ROOT_USER: ${STORAGE_ACCESS_KEY:-minioadmin} | |
| MINIO_ROOT_PASSWORD: ${STORAGE_SECRET_KEY:-minioadmin} | |
| ports: | |
| - ${MINIO_PORT:-8484}:8484 | |
| - 9001:9001 | |
| volumes: | |
| - ./data/minio:/data | |
| mailhog: | |
| image: mailhog/mailhog | |
| environment: | |
| SMTP_HOST: ${AUTH_SMTP_HOST:-mailhog} | |
| SMTP_PORT: ${AUTH_SMTP_PORT:-1025} | |
| SMTP_PASS: ${AUTH_SMTP_PASS:-password} | |
| SMTP_USER: ${AUTH_SMTP_USER:-user} | |
| SMTP_SECURE: "${AUTH_SMTP_SECURE:-false}" | |
| SMTP_SENDER: ${AUTH_SMTP_SENDER:-hbp@hbp.com} | |
| ports: | |
| - ${AUTH_SMTP_PORT:-1025}:1025 | |
| - 8025:8025 | |
| volumes: | |
| - ./data/mailhog:/maildir | |
| zookeeper: | |
| image: confluentinc/cp-zookeeper:5.4.2 | |
| hostname: zookeeper | |
| container_name: zookeeper | |
| ports: | |
| - "2181:2181" | |
| environment: | |
| ZOOKEEPER_CLIENT_PORT: "2181" | |
| ZOOKEEPER_TICK_TIME: "2000" | |
| KAFKA_OPTS: "-Djava.security.auth.login.config=/etc/kafka/server-jaas.conf -Dzookeeper.authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider" | |
| volumes: | |
| - ./kafka/kafka/server-jaas.conf:/etc/kafka/server-jaas.conf:ro,z | |
| kafka1: | |
| image: confluentinc/cp-kafka:5.4.2 | |
| hostname: kafka1 | |
| container_name: kafka1 | |
| labels: | |
| - "custom.project=kafkajs" | |
| - "custom.service=kafka1" | |
| depends_on: | |
| - zookeeper | |
| ports: | |
| - "29092:29092" | |
| - "9092:9092" | |
| - "29093:29093" | |
| - "9093:9093" | |
| - "29094:29094" | |
| - "9094:9094" | |
| environment: | |
| KAFKA_ADVERTISED_HOST_NAME: kafka1 | |
| KAFKA_BROKER_ID: "0" | |
| KAFKA_ZOOKEEPER_CONNECT: "zookeeper:2181" | |
| KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT,PLAINTEXT:SASL_PLAINTEXT | |
| KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT | |
| KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka1:29092,PLAINTEXT_HOST://localhost:9092 | |
| KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true" | |
| KAFKA_DEFAULT_REPLICATION_FACTOR: "1" | |
| KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: "1" | |
| KAFKA_NUM_PARTITIONS: "1" | |
| KAFKA_DELETE_TOPIC_ENABLE: "true" | |
| KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: "0" | |
| KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: "PLAIN" | |
| KAFKA_SASL_ENABLED_MECHANISMS: "PLAIN,SCRAM-SHA-256,SCRAM-SHA-512" | |
| KAFKA_OPTS: "-Djava.security.auth.login.config=/opt/kafka/config/server-jaas.conf" | |
| KAFKA_AUTHORIZER_CLASS_NAME: "kafka.security.auth.SimpleAclAuthorizer" | |
| KAFKA_ALLOW_EVERYONE_IF_NO_ACL_FOUND: "true" | |
| # suppress verbosity | |
| # https://github.com/confluentinc/cp-docker-images/blob/master/debian/kafka/include/etc/confluent/docker/log4j.properties.template | |
| KAFKA_LOG4J_LOGGERS: "kafka.controller=INFO,kafka.producer.async.DefaultEventHandler=INFO,state.change.logger=INFO" | |
| CONFLUENT_SUPPORT_METRICS_ENABLE: "false" | |
| CONFLUENT_METRICS_REPORTER_TOPIC_REPLICAS: "1" | |
| volumes: | |
| - ./kafka/kafka/server-jaas.conf:/opt/kafka/config/server-jaas.conf:ro,z | |
| live-meeting-worker: | |
| build: | |
| context: ../python-api/live_meeting_worker # Path to the Dockerfile directory | |
| dockerfile: Dockerfile | |
| container_name: live-meeting-worker | |
| depends_on: | |
| - postgres # If it ever needs to interact with postgres directly | |
| environment: | |
| - OPENAI_API_KEY=${OPENAI_API_KEY} | |
| - NOTION_API_KEY=${NOTION_API_KEY} | |
| - NOTION_PARENT_PAGE_ID=${NOTION_PARENT_PAGE_ID} # Optional | |
| - DATABASE_URL=/app/data/live_meeting_tasks.db | |
| volumes: | |
| - ./worker_data:/app/data # For SQLite DB persistence | |
| ports: | |
| - "8001:8001" # Expose the port FastAPI runs on | |
| restart: always | |
| healthcheck: | |
| test: ["CMD", "curl", "-f", "http://localhost:8001/list_audio_devices"] # Basic healthcheck | |
| interval: 30s | |
| timeout: 10s | |
| retries: 3 | |
| start_period: 30s | |
| labels: | |
| - "traefik.enable=true" | |
| - "traefik.http.middlewares.strip-live-meeting-worker.stripprefix.prefixes=/v1/live-meeting-worker" | |
| # HTTP router (redirects to HTTPS) | |
| - "traefik.http.routers.live-meeting-worker-http.rule=Host(`${HOST_NAME:-localhost}`) && PathPrefix(`/v1/live-meeting-worker`)" | |
| - "traefik.http.routers.live-meeting-worker-http.entrypoints=web" | |
| - "traefik.http.routers.live-meeting-worker-http.middlewares=strip-live-meeting-worker@docker,https-redirect@docker" | |
| # HTTPS router | |
| - "traefik.http.routers.live-meeting-worker-https.rule=Host(`${HOST_NAME:-localhost}`) && PathPrefix(`/v1/live-meeting-worker`)" | |
| - "traefik.http.routers.live-meeting-worker-https.entrypoints=websecure" | |
| - "traefik.http.routers.live-meeting-worker-https.tls=true" | |
| - "traefik.http.routers.live-meeting-worker-https.tls.certresolver=le" | |
| - "traefik.http.routers.live-meeting-worker-https.middlewares=strip-live-meeting-worker@docker" | |
| - "traefik.http.routers.live-meeting-worker-https.service=live-meeting-worker-service" | |
| - "traefik.http.services.live-meeting-worker-service.loadbalancer.server.port=8001" | |
| optaplanner: | |
| image: atomic-scheduler:latest | |
| restart: always | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| environment: | |
| QUARKUS_DATASOURCE_JDBC_URL: jdbc:postgresql://postgres:5432/postgres | |
| QUARKUS_DATASOURCE_USERNAME: ${POSTGRES_USERNAME:-postgres} | |
| QUARKUS_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-secretpgpassword} | |
| QUARKUS_DATASOURCE_DB-KIND: postgresql | |
| USERNAME: admin | |
| PASSWORD: ${API_TOKEN:-secretapitoken} | |
| ports: | |
| - 8081:8081 | |
| healthcheck: | |
| test: ["CMD", "curl", "-f", "http://localhost:8081/q/health"] | |
| interval: 30s | |
| timeout: 10s | |
| retries: 3 | |
| start_period: 60s # Quarkus apps can take a moment to start | |
| app: | |
| build: | |
| context: ../../frontend-nextjs | |
| args: | |
| POSTGRAPHILE_GRAPHQL_URL: http://postgraphile:5000/graphql # Internal URL for server-side rendering or API routes if needed | |
| NEXT_PUBLIC_POSTGRAPHILE_GRAPHQL_URL: http://localhost:5000/graphql # URL for client-side | |
| NEXT_PUBLIC_EVENT_TO_QUEUE_AUTH_URL: https://${HOST_NAME:-localhost}/v1/functions/schedule-event/publisherScheduleEvent/schedule-event-auth | |
| NEXT_PUBLIC_EVENT_TO_QUEUE_SHORT_AUTH_URL: https://${HOST_NAME:-localhost}/v1/functions/schedule-event/publisherScheduleShortEvent/schedule-short-event-auth | |
| NEXT_PUBLIC_CALENDAR_TO_QUEUE_AUTH_URL: https://${HOST_NAME:-localhost}/v1/functions/schedule-assist/publisherScheduleMeeting/schedule-meeting-to-queue-auth | |
| NEXT_PUBLIC_FEATURES_APPLY_TO_EVENTS_AUTH_URL: https://${HOST_NAME:-localhost}/v1/functions/features-apply/publish-to-features-worker/features-worker-to-queue-auth | |
| NEXT_PUBLIC_METHOD_TO_SEARCH_INDEX_AUTH_URL: https://${HOST_NAME:-localhost}/v1/functions/events-search/eventsSearch/events-search-auth | |
| NEXT_PUBLIC_GOOGLE_CALENDAR_ANDROID_AUTH_URL: https://${HOST_NAME:-localhost}/v1/functions/google-api-auth/googleCalendarAndroidAuth/google-calendar-android-auth | |
| NEXT_PUBLIC_GOOGLE_CALENDAR_ANDROID_AUTH_REFRESH_URL: https://${HOST_NAME:-localhost}/v1/functions/google-api-auth/googleCalendarAndroidAuthRefresh/google-calendar-android-auth-refresh | |
| NEXT_PUBLIC_GOOGLE_ATOMIC_WEB_AUTH_REFRESH_URL: https://${HOST_NAME:-localhost}/v1/functions/google-api-auth/googleAtomicWebAuthRefresh/google-atomic-web-auth-refresh | |
| NEXT_PUBLIC_GOOGLE_CALENDAR_IOS_AUTH_REFRESH_URL: https://${HOST_NAME:-localhost}/v1/functions/google-api-auth/googleCalendarIosAuthRefresh/google-calendar-ios-auth-refresh | |
| NEXT_PUBLIC_GOOGLE_OAUTH_ATOMIC_WEB_API_START_URL: https://${HOST_NAME:-localhost}/api/google/start-oauth | |
| NEXT_PUBLIC_GOOGLE_OAUTH_ATOMIC_WEB_REDIRECT_URL: https://${HOST_NAME:-localhost}/api/google/oauth-callback | |
| GOOGLE_CLIENT_ID_ATOMIC_WEB: ${GOOGLE_CLIENT_ID_ATOMIC_WEB:-default_atomic_web_client_id} | |
| GOOGLE_CLIENT_SECRET_ATOMIC_WEB: ${GOOGLE_CLIENT_SECRET_ATOMIC_WEB:-default_atomic_web_secret} | |
| ZOOM_IV_FOR_PASS: ${ZOOM_IV_FOR_PASS:-default_iv} | |
| ZOOM_SALT_FOR_PASS: ${ZOOM_SALT_FOR_PASS:-default_salt} | |
| ZOOM_PASS_KEY: ${ZOOM_PASS_KEY:-default_zoom_pass_key} | |
| NEXT_PUBLIC_EMAIL_MEETING_INFO_TO_HOST_URL: https://${HOST_NAME:-localhost}/v1/functions/email-notification/meeting-info-host/meeting-info-to-host-auth | |
| NEXT_PUBLIC_EMAIL_MEETING_INVITE_URL: https://${HOST_NAME:-localhost}/v1/functions/email-notification/meeting-invite-email/meeting-invite-auth | |
| NEXT_PUBLIC_EMAIL_MEETING_CANCEL_URL: https://${HOST_NAME:-localhost}/v1/functions/email-notification/meeting-cancel-email/meeting-cancel-auth | |
| NEXT_PUBLIC_HANDSHAKE_URL: https://${HOST_NAME:-localhost}/v1/handshake/ | |
| NEXT_PUBLIC_DELETE_ZOOM_CONFERENCE_URL: https://${HOST_NAME:-localhost}/v1/functions/zoom-meeting/delZoomMeet/delete-zoom-meet-auth | |
| NEXT_PUBLIC_GOOGLE_CALENDAR_SYNC_URL: https://${HOST_NAME:-localhost}/v1/functions/google-calendar-sync/googleCalendarSync/google-calendar-sync-auth | |
| NEXT_PUBLIC_SELF_GOOGLE_CALENDAR_WATCH_URL: https://${HOST_NAME:-localhost}/v1/functions/google-calendar-sync/googleCalendarWatch/google-calendar-watch-auth | |
| NEXT_PUBLIC_GOOGLE_OAUTH_START_URL: https://${HOST_NAME:-localhost}/Auth/google/oauth-start | |
| NEXT_PUBLIC_CHAT_WS_API_URL: ws://localhost:3030 | |
| NEXT_PUBLIC_GOOGLE_PEOPLE_SYNC_URL: https://${HOST_NAME:-localhost}/v1/functions/google-calendar-sync/googlePeopleSync/google-contact-sync-auth | |
| NEXT_PUBLIC_ADD_DAILY_FEATURES_AUTOPILOT_URL: https://${HOST_NAME:-localhost}/v1/functions/autopilot/addDailyFeatures/add-daily-features-to-event-auth | |
| NEXT_PUBLIC_DELETE_SCHEDULED_EVENT_URL: https://${HOST_NAME:-localhost}/v1/functions/autopilot/deleteScheduledEvent/delete-scheduled-event-auth | |
| NEXT_PUBLIC_ZOOM_CREATE_MEETING_URL: https://${HOST_NAME:-localhost}/v1/functions/zoom-meeting/createZoomMeet/create-zoom-meet-auth | |
| NEXT_PUBLIC_ZOOM_UPDATE_MEETING_URL: https://${HOST_NAME:-localhost}/v1/functions/zoom-meeting/updateZoomMeet/update-zoom-meet-auth | |
| NEXT_PUBLIC_ZOOM_DELETE_MEETING_URL: https://${HOST_NAME:-localhost}/v1/functions/zoom-meeting/delZoomMeet/delete-zoom-meet-auth | |
| NEXT_PUBLIC_ZOOM_OAUTH_START_URL: https://${HOST_NAME:-localhost}/zoom/oauth-start | |
| NEXT_PUBLIC_LIVE_MEETING_WORKER_URL: http://live-meeting-worker:8001 | |
| container_name: app | |
| depends_on: | |
| - supertokens | |
| - live-meeting-worker # Add dependency if app should wait for worker | |
| labels: | |
| - "traefik.enable=true" | |
| # HTTP router for app (redirects to HTTPS) | |
| - "traefik.http.routers.app-http.rule=Host(`${HOST_NAME:-localhost}`) && PathPrefix(`/`)" | |
| - "traefik.http.routers.app-http.entrypoints=web" | |
| - "traefik.http.routers.app-http.middlewares=https-redirect@docker" # Apply global redirect | |
| # HTTPS router for app | |
| - "traefik.http.routers.app-https.rule=Host(`${HOST_NAME:-localhost}`) && PathPrefix(`/`)" | |
| - "traefik.http.routers.app-https.entrypoints=websecure" | |
| - "traefik.http.routers.app-https.tls=true" | |
| - "traefik.http.routers.app-https.tls.certresolver=le" | |
| - "traefik.http.routers.app-https.service=app-service" # Explicit service name | |
| - "traefik.http.services.app-service.loadbalancer.server.port=3000" | |
| healthcheck: | |
| test: ["CMD", "curl", "-f", "http://localhost:3000/"] # Check root path | |
| interval: 30s | |
| timeout: 10s | |
| retries: 3 | |
| start_period: 45s # Next.js apps can take a bit to start | |
| ports: | |
| - "3000:3000" | |
| # Add NEXT_PUBLIC_LIVE_MEETING_WORKER_URL to environment or build args | |
| # If it's passed during build time via build args: | |
| # build: | |
| # context: ../app_build_docker | |
| # args: | |
| # # ... other args | |
| # NEXT_PUBLIC_LIVE_MEETING_WORKER_URL: http://live-meeting-worker:8001 | |
| # If it's passed as a runtime environment variable (more common for URLs): | |
| environment: | |
| # ... (ensure all existing environment variables for 'app' are maintained) | |
| # Example of how it might be structured if environment is already used: | |
| # EXISTING_ENV_VAR: ${EXISTING_ENV_VAR} | |
| NEXT_PUBLIC_LIVE_MEETING_WORKER_URL: http://live-meeting-worker:8001 | |
| # PYTHON_API_SERVICE_BASE_URL: ${PYTHON_API_SERVICE_BASE_URL:-http://python-agent:5000} # Removed: python-agent service deprecated | |
| # The existing 'app' service definition is complex with many build args. | |
| # Need to be careful to merge this correctly. | |
| # Based on the structure, build args are used. So I will add it there. | |
| # python-agent: | |
| # NOTE: Service removed - python_agent_build_docker directory deleted (2025-02-03) | |
| # Reason: Duplicate functionality exists in backend/integrations/ | |
| # - Notion integration: backend/integrations/notion_service.py | |
| # - Deepgram integration: backend/integrations/deepgram_service.py | |
| # - All other services have real implementations | |
| # This service contained placeholder Celery tasks that returned "method": "placeholder" | |
| # To restore this service, uncomment the following and restore python_agent_build_docker directory | |
| # python-agent: | |
| # build: | |
| # context: ../python_agent_build_docker | |
| # dockerfile: Dockerfile | |
| # container_name: python-agent | |
| # depends_on: | |
| # - postgres | |
| # environment: | |
| # - NOTION_API_TOKEN=${NOTION_API_TOKEN:-default_notion_token} | |
| # - NOTION_NOTES_DATABASE_ID=${NOTION_NOTES_DATABASE_ID:-default_notes_db_id} | |
| # - DEEPGRAM_API_KEY=${DEEPGRAM_API_KEY:-default_deepgram_key} | |
| # - NOTION_RESEARCH_PROJECTS_DB_ID=${NOTION_RESEARCH_PROJECTS_DB_ID:-default_research_projects_db_id} | |
| # - NOTION_RESEARCH_TASKS_DB_ID=${NOTION_RESEARCH_TASKS_DB_ID:-default_research_tasks_db_id} | |
| # - OPENAI_API_KEY=${OPENAI_API_KEY:-sk-default-openai-key} | |
| # - LANCEDB_URI=/lancedb_data/atom_core_db | |
| # - LANCEDB_TABLE_NAME=${LANCEDB_TABLE_NAME:-meeting_transcripts_embeddings} | |
| # - PYTHONUNBUFFERED=1 | |
| # volumes: | |
| # - .:/app/project | |
| # - ${LANCEDB_HOST_PATH:-./lance_db_data_shared}:/lancedb_data | |
| # tty: true | |
| # stdin_open: true | |
| ingestion-pipeline-service: | |
| build: | |
| context: ../python-api/ingestion_pipeline | |
| dockerfile: Dockerfile | |
| container_name: ingestion-pipeline-service | |
| restart: unless-stopped | |
| depends_on: | |
| - functions # Example dependency, adjust as needed | |
| environment: | |
| - NOTION_API_KEY=${NOTION_API_KEY} | |
| - NOTION_TRANSCRIPTS_DATABASE_ID=${NOTION_TRANSCRIPTS_DATABASE_ID} | |
| - OPENAI_API_KEY=${OPENAI_API_KEY} | |
| - LANCEDB_URI=/lancedb_data/atom_core_db # Points to the mounted volume + DB name | |
| - ATOM_USER_ID_FOR_INGESTION=${ATOM_USER_ID_FOR_INGESTION:-default_atom_user_pipeline} | |
| - PROCESSING_MODE=${PROCESSING_MODE:-incremental} | |
| - LOG_LEVEL=${LOG_LEVEL:-INFO} | |
| - PYTHONUNBUFFERED=1 | |
| volumes: | |
| # Mount the shared LanceDB data volume | |
| - ${LANCEDB_HOST_PATH:-./lance_db_data_shared}:/lancedb_data | |
| ports: | |
| - "8002:8002" # Expose for triggering, can be removed if triggered internally | |
| healthcheck: | |
| test: | |
| [ | |
| "CMD-SHELL", | |
| "curl -f http://localhost:8002/ingestion-status || exit 1", | |
| ] | |
| interval: 60s | |
| timeout: 10s | |
| retries: 3 | |
| start_period: 60s | |
| redis: | |
| image: "redis:alpine" | |
| container_name: redis | |
| expose: | |
| - 6379 | |
| healthcheck: | |
| test: ["CMD", "redis-cli", "ping"] | |
| interval: 1s | |
| timeout: 3s | |
| retries: 30 | |
| celery-worker: | |
| build: | |
| context: ../python_agent_build_docker | |
| dockerfile: Dockerfile | |
| container_name: celery-worker | |
| command: celery -A project.celery_app worker --loglevel=info | |
| volumes: | |
| - .:/app/project | |
| - ${LANCEDB_HOST_PATH:-./lance_db_data_shared}:/lancedb_data | |
| depends_on: | |
| - redis | |
| - postgres | |
| environment: | |
| - CELERY_BROKER_URL=redis://redis:6379/0 | |
| - CELERY_RESULT_BACKEND=redis://redis:6379/0 | |
| - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD:-secretpgpassword}@postgres:5432/postgres | |
| - NOTION_API_TOKEN=${NOTION_API_TOKEN:-default_notion_token} | |
| - NOTION_NOTES_DATABASE_ID=${NOTION_NOTES_DATABASE_ID:-default_notes_db_id} | |
| - DEEPGRAM_API_KEY=${DEEPGRAM_API_KEY:-default_deepgram_key} | |
| - NOTION_RESEARCH_PROJECTS_DB_ID=${NOTION_RESEARCH_PROJECTS_DB_ID:-default_research_projects_db_id} | |
| - NOTION_RESEARCH_TASKS_DB_ID=${NOTION_RESEARCH_TASKS_DB_ID:-default_research_tasks_db_id} | |
| - OPENAI_API_KEY=${OPENAI_API_KEY:-sk-default-openai-key} | |
| - LANCEDB_URI=/lancedb_data/atom_core_db | |
| - LANCEDB_TABLE_NAME=${LANCEDB_TABLE_NAME:-meeting_transcripts_embeddings} | |
| - PYTHONUNBUFFERED=1 | |
| # celery-worker: | |
| # NOTE: Service removed - python_agent_build_docker directory deleted (2025-02-03) | |
| # Celery background tasks with placeholder implementations (Slack, Email, Asana all returned "method": "placeholder") | |
| # Real implementations exist in backend/integrations/ | |
| # To restore, uncomment and restore python_agent_build_docker directory | |
| # celery-worker: | |
| # build: | |
| # context: ../python_agent_build_docker | |
| # dockerfile: Dockerfile | |
| # container_name: celery-worker | |
| # command: celery -A project.celery_app worker --loglevel=info | |
| # volumes: | |
| # - .:/app/project | |
| # - ${LANCEDB_HOST_PATH:-./lance_db_data_shared}:/lancedb_data | |
| # depends_on: | |
| # - redis | |
| # - postgres | |
| # environment: | |
| # - CELERY_BROKER_URL=redis://redis:6379/0 | |
| # - CELERY_RESULT_BACKEND=redis://redis:6379/0 | |
| # - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD:-secretpgpassword}@postgres:5432/postgres | |
| # - NOTION_API_TOKEN=${NOTION_API_TOKEN:-default_notion_token} | |
| # - NOTION_NOTES_DATABASE_ID=${NOTION_NOTES_DATABASE_ID:-default_notes_db_id} | |
| # - DEEPGRAM_API_KEY=${DEEPGRAM_API_KEY:-default_deepgram_key} | |
| # - NOTION_RESEARCH_PROJECTS_DB_ID=${NOTION_RESEARCH_PROJECTS_DB_ID:-default_research_projects_db_id} | |
| # - NOTION_RESEARCH_TASKS_DB_ID=${NOTION_RESEARCH_TASKS_DB_ID:-default_research_tasks_db_id} | |
| # - OPENAI_API_KEY=${OPENAI_API_KEY:-sk-default-openai-key} | |
| # - LANCEDB_URI=/lancedb_data/atom_core_db | |
| # - LANCEDB_TABLE_NAME=${LANCEDB_TABLE_NAME:-meeting_transcripts_embeddings} | |
| # - PYTHONUNBUFFERED=1 | |
| # celery-beat: | |
| # NOTE: Service removed - python_agent_build_docker directory deleted (2025-02-03) | |
| # Celery beat scheduler for placeholder background tasks | |
| # To restore, uncomment and restore python_agent_build_docker directory | |
| # celery-beat: | |
| # build: | |
| # context: ../python_agent_build_docker | |
| # dockerfile: Dockerfile | |
| # container_name: celery-beat | |
| # command: celery -A project.celery_app beat --loglevel=info | |
| # volumes: | |
| # - .:/app/project | |
| # depends_on: | |
| # - redis | |
| # - postgres | |
| # environment: | |
| # - CELERY_BROKER_URL=redis://redis:6379/0 | |
| # - CELERY_RESULT_BACKEND=redis://redis:6379/0 | |
| # - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD:-secretpgpassword}@postgres:5432/postgres | |
| workflows-api: | |
| build: | |
| context: ../python-api/workflows | |
| dockerfile: Dockerfile | |
| container_name: workflows-api | |
| restart: unless-stopped | |
| depends_on: | |
| - postgres | |
| - redis | |
| environment: | |
| - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/postgres | |
| - CELERY_BROKER_URL=redis://redis:6379/0 | |
| - CELERY_RESULT_BACKEND=redis://redis:6379/0 | |
| - OPENAI_API_KEY=${OPENAI_API_KEY} | |
| - NOTION_API_KEY=${NOTION_API_KEY} | |
| ports: | |
| - "8003:8003" | |
| healthcheck: | |
| test: ["CMD-SHELL", "curl -f http://localhost:8003/healthz || exit 1"] | |
| interval: 30s | |
| timeout: 10s | |
| retries: 3 | |
| start_period: 30s | |
| labels: | |
| - "traefik.enable=true" | |
| - "traefik.http.middlewares.strip-workflows-api.stripprefix.prefixes=/api/workflows" | |
| - "traefik.http.routers.workflows-api-http.rule=Host(`${HOST_NAME:-localhost}`) && PathPrefix(`/api/workflows`)" | |
| - "traefik.http.routers.workflows-api-http.entrypoints=web" | |
| - "traefik.http.routers.workflows-api-http.middlewares=strip-workflows-api@docker,https-redirect@docker" | |
| - "traefik.http.routers.workflows-api-https.rule=Host(`${HOST_NAME:-localhost}`) && PathPrefix(`/api/workflows`)" | |
| - "traefik.http.routers.workflows-api-https.entrypoints=websecure" | |
| - "traefik.http.routers.workflows-api-https.tls=true" | |
| - "traefik.http.routers.workflows-api-https.tls.certresolver=le" | |
| - "traefik.http.routers.workflows-api-https.middlewares=strip-workflows-api@docker" | |
| - "traefik.http.routers.workflows-api-https.service=workflows-api-service" | |
| - "traefik.http.services.workflows-api-service.loadbalancer.server.port=8003" | |
| dropbox-api: | |
| build: | |
| context: ../python-api/dropbox_service | |
| dockerfile: Dockerfile | |
| container_name: dropbox-api | |
| restart: unless-stopped | |
| ports: | |
| - "5001:5001" | |
| healthcheck: | |
| test: ["CMD-SHELL", "curl -f http://localhost:5001/ || exit 1"] | |
| interval: 30s | |
| timeout: 10s | |
| retries: 3 | |
| start_period: 30s | |
| labels: | |
| - "traefik.enable=true" | |
| - "traefik.http.routers.dropbox-api.rule=Host(`${HOST_NAME:-localhost}`) && PathPrefix(`/api/dropbox`)" | |
| - "traefik.http.routers.dropbox-api.entrypoints=websecure" | |
| - "traefik.http.routers.dropbox-api.tls=true" | |
| - "traefik.http.routers.dropbox-api.tls.certresolver=le" | |
| - "traefik.http.services.dropbox-api.loadbalancer.server.port=5001" | |
| volumes: | |
| project_node_modules: | |
| functions_node_modules: | |