services: redis: image: redis:8.10.2-alpine restart: always volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 2s timeout: 1s retries: 10 start_period: 2s trawl: image: ghcr.io/germondai/trawl:latest restart: always ports: - "${PORT:-8191}:8191" # MITM proxy (only when MITM_ENABLED=true). CA cert at :8191/proxy-ca.crt - "${MITM_PORT:-8192}:${MITM_PORT:-8192}" shm_size: 1gb environment: SESSION_CACHE_DRIVER: ${SESSION_CACHE_DRIVER:-redis} REDIS_URL: redis://redis:6379 REDIS_SESSION_TTL_SECONDS: ${REDIS_SESSION_TTL_SECONDS:-3600} MEMORY_SESSION_CACHE_MAX_ENTRIES: ${MEMORY_SESSION_CACHE_MAX_ENTRIES:-1000} REDIS_CONNECT_TIMEOUT_MS: ${REDIS_CONNECT_TIMEOUT_MS:-5000} REDIS_RETRY_DELAY_MS: ${REDIS_RETRY_DELAY_MS:-5000} BROWSER_POOL_SIZE: ${BROWSER_POOL_SIZE:-1} LOG_LEVEL: ${LOG_LEVEL:-info} SCRAPE_MIN_TIER: ${SCRAPE_MIN_TIER:-1} TIER1_TRANSPORT: ${TIER1_TRANSPORT:-bun} SCRAPE_MAX_TIMEOUT_MS: ${SCRAPE_MAX_TIMEOUT_MS:-60000} BROWSER_MAX_CONTENT_PROCESSES: ${BROWSER_MAX_CONTENT_PROCESSES:-2} BROWSER_HEADFUL_POOL_SIZE: ${BROWSER_HEADFUL_POOL_SIZE:-0} BROWSER_ACQUIRE_TIMEOUT_MS: ${BROWSER_ACQUIRE_TIMEOUT_MS:-15000} BROWSER_RECYCLE_AFTER_CONTEXTS: ${BROWSER_RECYCLE_AFTER_CONTEXTS:-8} BROWSER_STALL_TIMEOUT_MS: ${BROWSER_STALL_TIMEOUT_MS:-180000} BROWSER_CLOSE_TIMEOUT_MS: ${BROWSER_CLOSE_TIMEOUT_MS:-10000} BROWSER_SHUTDOWN_DRAIN_MS: ${BROWSER_SHUTDOWN_DRAIN_MS:-0} BROWSER_LAUNCH_TIMEOUT_MS: ${BROWSER_LAUNCH_TIMEOUT_MS:-90000} SCREENSHOT_SETTLE_MS: ${SCREENSHOT_SETTLE_MS:-3000} SCREENSHOT_TIMEOUT_MS: ${SCREENSHOT_TIMEOUT_MS:-10000} SCREENSHOT_JPEG_QUALITY: ${SCREENSHOT_JPEG_QUALITY:-60} SCREENSHOT_MAX_BYTES: ${SCREENSHOT_MAX_BYTES:-4000000} BLOCKED_EVIDENCE_MAX_HTML_CHARS: ${BLOCKED_EVIDENCE_MAX_HTML_CHARS:-512000} DIAGNOSTICS_MAX_CONSOLE_ENTRIES: ${DIAGNOSTICS_MAX_CONSOLE_ENTRIES:-500} DIAGNOSTICS_MAX_NETWORK_ENTRIES: ${DIAGNOSTICS_MAX_NETWORK_ENTRIES:-1000} DIAGNOSTICS_MAX_STRING_CHARS: ${DIAGNOSTICS_MAX_STRING_CHARS:-2000} DIAGNOSTICS_MAX_TOTAL_CHARS: ${DIAGNOSTICS_MAX_TOTAL_CHARS:-1000000} DIAGNOSTICS_SIZE_TIMEOUT_MS: ${DIAGNOSTICS_SIZE_TIMEOUT_MS:-2000} REDIRECT_MAX_ENTRIES: ${REDIRECT_MAX_ENTRIES:-50} REDIRECT_MAX_URL_CHARS: ${REDIRECT_MAX_URL_CHARS:-2000} REDIRECT_MAX_TOTAL_CHARS: ${REDIRECT_MAX_TOTAL_CHARS:-1000000} CAPTURE_MAX_PATTERNS: ${CAPTURE_MAX_PATTERNS:-10} CAPTURE_MAX_RESPONSES: ${CAPTURE_MAX_RESPONSES:-5} CAPTURE_MAX_BODY_BYTES: ${CAPTURE_MAX_BODY_BYTES:-5242880} CAPTURE_MAX_TOTAL_BYTES: ${CAPTURE_MAX_TOTAL_BYTES:-10485760} CAPTURE_MAX_READ_BYTES: ${CAPTURE_MAX_READ_BYTES:-10485760} CAPTURE_MAX_METADATA_CHARS: ${CAPTURE_MAX_METADATA_CHARS:-2000} CAPTURE_BODY_TIMEOUT_MS: ${CAPTURE_BODY_TIMEOUT_MS:-5000} CAPTURE_SETTLE_MS: ${CAPTURE_SETTLE_MS:-15000} CAPTURE_MAX_SETTLE_MS: ${CAPTURE_MAX_SETTLE_MS:-60000} CAPTURE_IDLE_FLOOR_MS: ${CAPTURE_IDLE_FLOOR_MS:-5000} MHTML_MAX_PARTS: ${MHTML_MAX_PARTS:-200} MHTML_MAX_PART_BYTES: ${MHTML_MAX_PART_BYTES:-2097152} MHTML_MAX_TOTAL_CHARS: ${MHTML_MAX_TOTAL_CHARS:-8388608} MHTML_MAX_INFLIGHT_READS: ${MHTML_MAX_INFLIGHT_READS:-32} MHTML_MAX_OMISSION_RECORDS: ${MHTML_MAX_OMISSION_RECORDS:-100} STT_URL: ${STT_URL:-} STT_API_KEY: ${STT_API_KEY:-} FFMPEG_PATH: ${FFMPEG_PATH:-} MCP_ENABLED: ${MCP_ENABLED:-false} MCP_ALLOWED_ORIGINS: ${MCP_ALLOWED_ORIGINS:-} METRICS_DASHBOARD_ENABLED: ${METRICS_DASHBOARD_ENABLED:-false} METRICS_DASHBOARD_TOKEN: ${METRICS_DASHBOARD_TOKEN:-} METRICS_DB_PATH: ${METRICS_DB_PATH:-/data/metrics/trawl.sqlite} SCRAPE_PROXY_SELECTION: ${SCRAPE_PROXY_SELECTION:-failover} PROXY_URL: ${PROXY_URL:-} PROXY_LIST_FILE: ${PROXY_LIST_FILE:-} RESIDENTIAL_PROXY_URL: ${RESIDENTIAL_PROXY_URL:-} RESIDENTIAL_PROXY_LIST_FILE: ${RESIDENTIAL_PROXY_LIST_FILE:-} MITM_ENABLED: ${MITM_ENABLED:-false} MITM_HOST: ${MITM_HOST:-0.0.0.0} MITM_PORT: ${MITM_PORT:-8192} MITM_CA_DIR: ${MITM_CA_DIR:-/data/proxy-ca} MITM_MAX_TIER: ${MITM_MAX_TIER:-4} MITM_ALWAYS_SCRAPE: ${MITM_ALWAYS_SCRAPE:-false} MITM_ESCALATE_429: ${MITM_ESCALATE_429:-false} MITM_DEBUG: ${MITM_DEBUG:-false} volumes: - trawl_proxy_ca:${MITM_CA_DIR:-/data/proxy-ca} - trawl_metrics:/data/metrics depends_on: redis: condition: service_healthy healthcheck: test: ["CMD", "curl", "-sf", "http://localhost:8191/health"] interval: 30s timeout: 10s retries: 3 start_period: 90s volumes: redis_data: trawl_proxy_ca: trawl_metrics: