name: dataops-test services: postgres: image: pgvector/pgvector:pg16 environment: POSTGRES_DB: dataops POSTGRES_USER: dataops POSTGRES_PASSWORD: dataops-test-password ports: - "15432:5432" volumes: - dataops-test-postgres:/var/lib/postgresql/data - ./postgres/init:/docker-entrypoint-initdb.d:ro - ../../database:/dataops-schema:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U dataops -d dataops"] interval: 5s timeout: 5s retries: 20 networks: - dataops-test-net source-postgres: image: postgres:16-alpine environment: POSTGRES_DB: acceptance POSTGRES_USER: source_reader POSTGRES_PASSWORD: source-test-password ports: - "25432:5432" volumes: - dataops-test-source-postgres:/var/lib/postgresql/data - ./datasources/postgres/init.sql:/docker-entrypoint-initdb.d/010-acceptance.sql:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U source_reader -d acceptance"] interval: 5s timeout: 5s retries: 20 networks: - dataops-test-net source-mysql: image: mysql:8.4 environment: MYSQL_DATABASE: acceptance MYSQL_USER: source_reader MYSQL_PASSWORD: source-test-password MYSQL_ROOT_PASSWORD: source-root-test-password ports: - "23306:3306" volumes: - dataops-test-source-mysql:/var/lib/mysql - ./datasources/mysql/init.sql:/docker-entrypoint-initdb.d/010-acceptance.sql:ro healthcheck: test: - CMD-SHELL - mysqladmin ping -h 127.0.0.1 -u source_reader -psource-test-password --silent interval: 5s timeout: 5s retries: 30 start_period: 20s networks: - dataops-test-net neo4j: image: neo4j:5.26-community environment: NEO4J_AUTH: neo4j/Passw0rd NEO4J_server_memory_heap_initial__size: 256m NEO4J_server_memory_heap_max__size: 512m NEO4J_server_memory_pagecache_size: 256m ports: - "17474:7474" - "17687:7687" volumes: - dataops-test-neo4j:/data healthcheck: test: ["CMD-SHELL", "cypher-shell -u neo4j -p Passw0rd 'RETURN 1' >/dev/null 2>&1"] interval: 10s timeout: 10s retries: 30 start_period: 20s networks: - dataops-test-net minio: image: minio/minio:RELEASE.2025-04-22T22-12-26Z command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: dataops-test MINIO_ROOT_PASSWORD: dataops-test-password ports: - "19000:9000" - "19001:9001" volumes: - dataops-test-minio:/data healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] interval: 5s timeout: 5s retries: 20 networks: - dataops-test-net minio-init: image: minio/mc:RELEASE.2025-04-16T18-13-26Z depends_on: minio: condition: service_healthy entrypoint: - /bin/sh - -c - >- mc alias set local http://minio:9000 dataops-test dataops-test-password && mc mb --ignore-existing local/dataops-bucket restart: "no" networks: - dataops-test-net n8n: image: n8nio/n8n:1.100.1 environment: DB_TYPE: postgresdb DB_POSTGRESDB_HOST: postgres DB_POSTGRESDB_PORT: 5432 DB_POSTGRESDB_DATABASE: n8n DB_POSTGRESDB_USER: dataops DB_POSTGRESDB_PASSWORD: dataops-test-password N8N_HOST: localhost N8N_PORT: 5678 N8N_PROTOCOL: http N8N_SECURE_COOKIE: "false" N8N_ENCRYPTION_KEY: dataops-local-test-encryption-key N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: "true" WEBHOOK_URL: http://localhost:15678/ GENERIC_TIMEZONE: Asia/Shanghai TZ: Asia/Shanghai ports: - "15678:5678" volumes: - dataops-test-n8n:/home/node/.n8n depends_on: postgres: condition: service_healthy healthcheck: test: ["CMD-SHELL", "wget --spider -q http://127.0.0.1:5678/healthz"] interval: 10s timeout: 5s retries: 30 start_period: 30s networks: - dataops-test-net kestra: image: kestra/kestra:v1.3.20 command: - server - standalone - --worker-thread=16 - --config - /etc/kestra/application.yml stop_grace_period: 6m environment: KESTRA_DB_HOST: postgres KESTRA_DB_NAME: kestra KESTRA_DB_USERNAME: dataops KESTRA_DB_PASSWORD: dataops-test-password KESTRA_USERNAME: ${KESTRA_USERNAME:-admin@dataops.local} KESTRA_PASSWORD: ${KESTRA_PASSWORD:-DataOpsKestra1!} ports: - "127.0.0.1:18080:8080" volumes: - dataops-test-kestra:/app/storage - ./kestra/application.yml:/etc/kestra/application.yml:ro depends_on: postgres: condition: service_healthy healthcheck: test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:8081/health"] interval: 10s timeout: 5s retries: 30 start_period: 30s networks: - dataops-test-net kestra-mcp: image: ghcr.io/kestra-io/mcp-server-python@sha256:1fd62028f60914af31e244ddb0086ed5017420313e2c8547ea9c01b8d24dfc1d profiles: - kestra-mcp stdin_open: true environment: KESTRA_BASE_URL: http://kestra:8080/api/v1 KESTRA_TENANT_ID: main KESTRA_USERNAME: ${KESTRA_USERNAME:-admin@dataops.local} KESTRA_PASSWORD: ${KESTRA_PASSWORD:-DataOpsKestra1!} KESTRA_MCP_DISABLED_TOOLS: ee,files,kv,namespace KESTRA_MCP_LOG_LEVEL: ERROR depends_on: kestra: condition: service_healthy networks: - dataops-test-net dataops-scheduling-mcp: image: dataops-platform-mcp:local build: context: ../.. dockerfile: deploy/docker/mcp.Dockerfile profiles: - dataops-mcp stdin_open: true read_only: true tmpfs: - /tmp:size=32m,mode=1777 pids_limit: 64 environment: DATAOPS_MCP_SUBJECT: ${DATAOPS_MCP_SUBJECT:-} DATAOPS_MCP_ROLES: ${DATAOPS_MCP_ROLES:-} DATAOPS_MCP_BUSINESS_DOMAINS: ${DATAOPS_MCP_BUSINESS_DOMAINS:-} DATAOPS_MCP_ENVIRONMENTS: ${DATAOPS_MCP_ENVIRONMENTS:-} DATAOPS_MCP_CORRELATION_ID: ${DATAOPS_MCP_CORRELATION_ID:-} DATAOPS_MCP_DATABASE_URL: postgresql://dataops:dataops-test-password@postgres:5432/dataops KESTRA_BASE_URL: http://kestra:8080/api/v1 KESTRA_TENANT_ID: main KESTRA_USERNAME: ${KESTRA_USERNAME:-admin@dataops.local} KESTRA_PASSWORD: ${KESTRA_PASSWORD:-DataOpsKestra1!} RUNNER_TASK_TOKEN_SECRET: ${RUNNER_TASK_TOKEN_SECRET:-dataops-local-runner-task-token-secret-change-me} RUNNER_TASK_TOKEN_TTL_SECONDS: 60 command: - --kind - scheduling - --factory - app.core.mcp.bootstrap:build_scheduling_gateway depends_on: postgres: condition: service_healthy kestra: condition: service_healthy runner: condition: service_healthy networks: - dataops-test-net dataops-context-mcp: image: dataops-platform-mcp:local build: context: ../.. dockerfile: deploy/docker/mcp.Dockerfile profiles: - dataops-mcp stdin_open: true read_only: true tmpfs: - /tmp:size=32m,mode=1777 pids_limit: 64 environment: DATAOPS_MCP_SUBJECT: ${DATAOPS_MCP_SUBJECT:-} DATAOPS_MCP_ROLES: ${DATAOPS_MCP_ROLES:-} DATAOPS_MCP_BUSINESS_DOMAINS: ${DATAOPS_MCP_BUSINESS_DOMAINS:-} DATAOPS_MCP_ENVIRONMENTS: ${DATAOPS_MCP_ENVIRONMENTS:-} DATAOPS_MCP_CORRELATION_ID: ${DATAOPS_MCP_CORRELATION_ID:-} DATAOPS_MCP_DATABASE_URL: postgresql://dataops:dataops-test-password@postgres:5432/dataops DATAOPS_MCP_CONTEXT_MAX_CONCURRENCY: 10 command: - --kind - context - --factory - app.core.mcp.bootstrap:build_context_service depends_on: postgres: condition: service_healthy networks: - dataops-test-net runner: build: context: ../.. dockerfile: deploy/docker/runner.Dockerfile environment: RUNNER_LISTEN_HOST: 0.0.0.0 RUNNER_LISTEN_PORT: 5600 RUNNER_WORKERS: 2 RUNNER_THREADS: 2 RUNNER_TASK_TOKEN_SECRET: ${RUNNER_TASK_TOKEN_SECRET:-dataops-local-runner-task-token-secret-change-me} RUNNER_TASK_TOKEN_TTL_SECONDS: 60 RUNNER_DATASOURCE_POOL_SIZE: 1 RUNNER_DATASOURCE_MAX_OVERFLOW: 1 RUNNER_DATASOURCE_MAX_IDLE_POOLS: 4 RUNNER_DATASOURCE_CONNECTION_BUDGET: 32 RUNNER_HTTP_ALLOWED_HOSTS: ${RUNNER_HTTP_ALLOWED_HOSTS:-} DATABASE_URL: postgresql://dataops:dataops-test-password@postgres:5432/dataops NEO4J_URI: bolt://neo4j:7687 NEO4J_USER: neo4j NEO4J_PASSWORD: Passw0rd DATASOURCE_CREDENTIAL_MASTER_KEY: ${DATASOURCE_CREDENTIAL_MASTER_KEY:-MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=} DATASOURCE_CREDENTIAL_KEY_VERSION: ${DATASOURCE_CREDENTIAL_KEY_VERSION:-v1} ports: - "127.0.0.1:15600:5600" read_only: true tmpfs: - /tmp:size=64m,mode=1777 pids_limit: 128 deploy: resources: limits: cpus: "1.0" memory: 512M pids: 128 depends_on: postgres: condition: service_healthy neo4j: condition: service_healthy healthcheck: test: - CMD - python - -c - import urllib.request; urllib.request.urlopen('http://127.0.0.1:5600/health', timeout=5) interval: 10s timeout: 5s retries: 20 start_period: 20s networks: dataops-test-net: aliases: - dataops-runner backend: build: context: ../.. dockerfile: deploy/docker/backend.Dockerfile environment: FLASK_ENV: production LISTEN_HOST: 0.0.0.0 LISTEN_PORT: 5500 GUNICORN_WORKERS: 2 DATABASE_URL: postgresql://dataops:dataops-test-password@postgres:5432/dataops NEO4J_URI: bolt://neo4j:7687 NEO4J_HTTP_URI: http://neo4j:7474 NEO4J_USER: neo4j NEO4J_PASSWORD: Passw0rd NEO4J_ENCRYPTED: "false" MINIO_HOST: minio:9000 MINIO_USER: dataops-test MINIO_PASSWORD: dataops-test-password MINIO_BUCKET: dataops-bucket MINIO_SECURE: "false" DATAFLOW_DEFAULT_DB_HOST: postgres DATAFLOW_DEFAULT_DB_PORT: 5432 DATAFLOW_DEFAULT_DB_NAME: dataops DATAFLOW_SCHEMA: dags N8N_API_URL: http://n8n:5678 N8N_API_KEY: ${N8N_API_KEY:-} API_BASE_URL: http://backend:5500/api DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY:-} LLM_BASE_URL: https://api.deepseek.com LLM_MODEL_NAME: deepseek-chat SECRET_KEY: dataops-local-test-secret-key DATASOURCE_CREDENTIAL_MASTER_KEY: ${DATASOURCE_CREDENTIAL_MASTER_KEY:-MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=} DATASOURCE_CREDENTIAL_KEY_VERSION: ${DATASOURCE_CREDENTIAL_KEY_VERSION:-v1} LOG_DIR: /app/logs LOG_TO_CONSOLE: "true" ports: - "15500:5500" volumes: - dataops-test-backend-logs:/app/logs - dataops-test-upload:/data/upload - dataops-test-archive:/data/archive depends_on: postgres: condition: service_healthy neo4j: condition: service_healthy minio-init: condition: service_completed_successfully healthcheck: test: - CMD - python - -c - import urllib.request; urllib.request.urlopen('http://127.0.0.1:5500/api/system/health', timeout=5) interval: 10s timeout: 10s retries: 20 start_period: 20s networks: - dataops-test-net frontend: build: context: ../.. dockerfile: deploy/docker/frontend.Dockerfile args: VUE_APP_N8N_URL: http://localhost:15678 VUE_APP_N8N_CHAT_URL: "" VUE_APP_MINIO_PUBLIC_URL: http://localhost:19000/dataops-bucket VUE_APP_PREVIEW_URL: "" ports: - "18183:80" depends_on: backend: condition: service_healthy healthcheck: test: ["CMD-SHELL", "wget --spider -q http://127.0.0.1/"] interval: 10s timeout: 5s retries: 20 networks: - dataops-test-net networks: dataops-test-net: name: dataops-test-net volumes: dataops-test-postgres: dataops-test-source-postgres: dataops-test-source-mysql: dataops-test-neo4j: dataops-test-minio: dataops-test-n8n: dataops-test-kestra: dataops-test-backend-logs: dataops-test-upload: dataops-test-archive: