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: