version: '3.8' services: # ============================================================================ # DATABASES # ============================================================================ postgres: image: postgres:15-alpine container_name: flowfish-postgres environment: POSTGRES_USER: flowfish POSTGRES_PASSWORD: flowfish123 POSTGRES_DB: flowfish ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data - ../../schemas/postgresql-schema.sql:/docker-entrypoint-initdb.d/01-schema.sql:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U flowfish"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped networks: - flowfish-network redis: image: redis:7-alpine container_name: flowfish-redis command: redis-server --requirepass redis123 ports: - "6379:6379" volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "-a", "redis123", "ping"] interval: 10s timeout: 3s retries: 5 restart: unless-stopped networks: - flowfish-network clickhouse: image: clickhouse/clickhouse-server:23-alpine container_name: flowfish-clickhouse environment: CLICKHOUSE_DB: flowfish CLICKHOUSE_USER: flowfish CLICKHOUSE_PASSWORD: flowfish123 ports: - "8123:8123" # HTTP - "9000:9000" # TCP volumes: - clickhouse_data:/var/lib/clickhouse - ../../schemas/clickhouse-events-schema.sql:/docker-entrypoint-initdb.d/01-events-schema.sql:ro - ../../schemas/clickhouse-change-events.sql:/docker-entrypoint-initdb.d/02-change-events.sql:ro ulimits: nofile: soft: 262144 hard: 262144 healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:8123/ping"] interval: 10s timeout: 5s retries: 10 start_period: 60s restart: unless-stopped networks: - flowfish-network # Neo4j Graph Database neo4j: image: neo4j:5.15-community container_name: flowfish-neo4j environment: NEO4J_AUTH: neo4j/flowfish123 NEO4J_server_memory_heap_initial__size: 512m NEO4J_server_memory_heap_max__size: 2G NEO4J_server_memory_pagecache_size: 1G NEO4J_server_default__listen__address: 0.0.0.0 NEO4J_ACCEPT_LICENSE_AGREEMENT: "yes" ports: - "7474:7474" # HTTP - "7687:7687" # Bolt volumes: - neo4j_data:/data - neo4j_logs:/logs healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:7474"] interval: 30s timeout: 10s retries: 5 start_period: 60s restart: unless-stopped networks: - flowfish-network # ============================================================================ # APPLICATIONS # ============================================================================ backend: image: taylanbakircioglu/flowfish:backend-latest # To build locally instead of pulling from Docker Hub, uncomment below: # build: # context: ../.. # dockerfile: backend/Dockerfile # volumes: # - ../../backend:/app container_name: flowfish-backend environment: # Database connections DATABASE_URL: postgresql://flowfish:flowfish123@postgres:5432/flowfish REDIS_URL: redis://:redis123@redis:6379/0 CLICKHOUSE_URL: http://flowfish:flowfish123@clickhouse:8123 NEO4J_BOLT_URI: bolt://neo4j:7687 NEO4J_HTTP_URI: http://neo4j:7474 NEO4J_USER: neo4j NEO4J_PASSWORD: flowfish123 NEO4J_DATABASE: neo4j # Application settings SECRET_KEY: super-secret-key-change-me-in-production JWT_EXPIRATION_HOURS: 1 CORS_ORIGINS: http://localhost:3000,http://frontend:3000 LOG_LEVEL: INFO # Feature flags ENABLE_LLM_ANALYSIS: false ENABLE_ANOMALY_DETECTION: true ENABLE_CHANGE_DETECTION: true # Local development settings ENV: development DEBUG: true # Cluster Manager gRPC endpoint CLUSTER_MANAGER_GRPC: cluster-manager:5001 # Encryption key for cluster credentials (shared with cluster-manager) FLOWFISH_ENCRYPTION_KEY: "Zo6CfvKB6y4IIPMAUJermGJ7UQm8wgjnvuehRGKY-sA=" ports: - "8000:8000" depends_on: postgres: condition: service_healthy redis: condition: service_healthy clickhouse: condition: service_healthy neo4j: condition: service_healthy cluster-manager: condition: service_started healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/v1/health')"] interval: 30s timeout: 10s retries: 3 restart: unless-stopped networks: - flowfish-network cluster-manager: image: taylanbakircioglu/flowfish:cluster-manager-latest # To build locally instead of pulling from Docker Hub, uncomment below: # build: # context: ../.. # dockerfile: services/cluster-manager/Dockerfile # volumes: # - ../../services/cluster-manager/app:/app/app container_name: flowfish-cluster-manager environment: SERVICE_NAME: cluster-manager GRPC_PORT: "5001" DATABASE_URL: postgresql://flowfish:flowfish123@postgres:5432/flowfish REDIS_URL: redis://:redis123@redis:6379/0 LOG_LEVEL: INFO FLOWFISH_ENCRYPTION_KEY: "Zo6CfvKB6y4IIPMAUJermGJ7UQm8wgjnvuehRGKY-sA=" ports: - "5001:5001" depends_on: postgres: condition: service_healthy redis: condition: service_healthy healthcheck: test: ["CMD", "python", "-c", "import grpc; ch=grpc.insecure_channel('localhost:5001'); ch.close()"] interval: 30s timeout: 10s retries: 3 start_period: 15s restart: unless-stopped networks: - flowfish-network frontend: image: taylanbakircioglu/flowfish:frontend-latest # To build locally instead of pulling from Docker Hub, uncomment below: # build: # context: ../.. # dockerfile: frontend/Dockerfile.production # volumes: # - ../../frontend/src:/app/src container_name: flowfish-frontend user: "0:0" environment: REACT_APP_API_URL: http://localhost:8000 REACT_APP_ENABLE_DARK_MODE: true REACT_APP_ENABLE_ANOMALY_DETECTION: true ports: - "3000:3000" depends_on: backend: condition: service_healthy healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3000"] interval: 30s timeout: 10s retries: 3 restart: unless-stopped networks: - flowfish-network # ============================================================================ # UTILITIES # ============================================================================ # Neo4j Browser (accessible via http://localhost:7474) # No separate container needed - Neo4j includes browser # Database initialization helper init-databases: image: alpine:latest container_name: flowfish-init command: - /bin/sh - -c - | echo "Waiting for all databases to be ready..." # Wait for services echo "All databases are ready!" # Neo4j schema initialization echo "Neo4j schema will be created automatically by application..." echo "Database initialization completed" depends_on: postgres: condition: service_healthy redis: condition: service_healthy clickhouse: condition: service_healthy neo4j: condition: service_healthy networks: - flowfish-network profiles: - init # Only run with docker-compose --profile init up # ============================================================================ # VOLUMES # ============================================================================ volumes: postgres_data: driver: local redis_data: driver: local clickhouse_data: driver: local neo4j_data: driver: local neo4j_logs: driver: local # ============================================================================ # NOTE: Inspektor Gadget (eBPF Data Collection) # ============================================================================ # Inspektor Gadget is a Kubernetes-native DaemonSet and CANNOT run in Docker # Compose. It requires the Kubernetes API for pod/container discovery and # metadata enrichment. To collect eBPF network/DNS/process events: # - Use the Kubernetes deployment (deployment/local-test/ or deployment/kubernetes-manifests/) # - Or run Flowfish here and add a remote Kubernetes cluster via Token method # in the UI (Clusters > Add Cluster > Token) # ============================================================================ # ============================================================================ # NETWORKS # ============================================================================ networks: flowfish-network: driver: bridge ipam: config: - subnet: 172.20.0.0/16