turnstone/docker-compose.submissions.yml
pyr0ball 82977f365b feat: periodic ingest scheduler + Orchard submission pipeline
Adds asyncio-native background scheduler (TURNSTONE_INGEST_INTERVAL,
default 900s) that runs batch ingest then pushes pattern-matched entries
to a remote CF harvest endpoint (TURNSTONE_SUBMIT_ENDPOINT).

- app/tasks/ingest_scheduler.py: IngestState, scheduler_loop, run_once,
  submit_matched, _query_matched_since — asyncio.Lock prevents concurrent runs
- app/rest.py: POST /api/ingest/batch (pre-parsed entry receiver),
  GET /api/tasks/ingest/status, POST /api/tasks/ingest (manual trigger),
  TURNSTONE_INGEST_INTERVAL + TURNSTONE_SUBMIT_ENDPOINT env wiring in lifespan
- docker-compose.submissions.yml: segregated daniel (8536) + xander (8537)
  receiving instances on Heimdall, isolated DBs under
  /devl/docker/turnstone-submissions/<node>/
- podman-standalone.sh: pass-through for TURNSTONE_SUBMIT_ENDPOINT +
  TURNSTONE_SOURCE_HOST
- app/ingest/mqtt_subscriber.py: MQTT log source adapter
- app/ingest/wazuh.py: Wazuh alert JSON adapter
- tests/test_ingest_wazuh.py: Wazuh adapter test suite
2026-05-20 08:57:25 -07:00

74 lines
2.3 KiB
YAML

# Turnstone — CF receiving instances for external node submissions.
#
# These are SEPARATE instances from the main Turnstone deployment. Each node
# that has TURNSTONE_SUBMIT_ENDPOINT configured pushes pattern-matched entries
# here. Each instance has its own isolated database. Avocet reads these
# databases for training data.
#
# Ports:
# 8536 → submissions-daniel (harvest.circuitforge.tech/daniel/*)
# 8537 → submissions-xander (harvest.circuitforge.tech/xander/*)
#
# Deploy on Heimdall:
# docker compose -f docker-compose.submissions.yml up -d
#
# Database locations:
# /devl/docker/turnstone-submissions/daniel/turnstone.db
# /devl/docker/turnstone-submissions/xander/turnstone.db
#
# These instances have TURNSTONE_INGEST_INTERVAL=0 — they only receive POSTs,
# they do not run their own scheduled ingest.
services:
submissions-daniel:
image: turnstone:latest
container_name: turnstone-submissions-daniel
restart: unless-stopped
ports:
- "8536:8534"
volumes:
- /devl/docker/turnstone-submissions/daniel:/data:z
- /devl/docker/turnstone-submissions/daniel/patterns:/patterns:ro
environment:
TURNSTONE_DB: /data/turnstone.db
TURNSTONE_PATTERNS: /patterns
TURNSTONE_SOURCE_HOST: submissions-daniel
TURNSTONE_INGEST_INTERVAL: "0"
PYTHONUNBUFFERED: "1"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8534/turnstone/health"]
interval: 30s
timeout: 10s
start_period: 20s
retries: 3
networks:
- caddy-internal
submissions-xander:
image: turnstone:latest
container_name: turnstone-submissions-xander
restart: unless-stopped
ports:
- "8537:8534"
volumes:
- /devl/docker/turnstone-submissions/xander:/data:z
- /devl/docker/turnstone-submissions/xander/patterns:/patterns:ro
environment:
TURNSTONE_DB: /data/turnstone.db
TURNSTONE_PATTERNS: /patterns
TURNSTONE_SOURCE_HOST: submissions-xander
TURNSTONE_INGEST_INTERVAL: "0"
PYTHONUNBUFFERED: "1"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8534/turnstone/health"]
interval: 30s
timeout: 10s
start_period: 20s
retries: 3
networks:
- caddy-internal
networks:
caddy-internal:
name: caddy-proxy_caddy-internal
external: true