Skip to main content

Docker Deployment

AiSOC ships three Compose flavors. Pick the one that matches what you are doing.

FilePurposeWhen to use
docker-compose.demo.ymlStreamlined demo with seeded dataTrying AiSOC for the first time
docker-compose.ymlFull developer stackActive development against real source
docker-compose.prod.ymlProduction-leaning stackSelf-hosting on a single VM

If you don't already have Docker installed, the simplest path is the one-click installer — it installs Docker (Engine + Compose v2 on Linux, Docker Desktop on macOS/Windows), Node, pnpm, and git idempotently, then runs the streamlined demo for you.

Streamlined demo

The fastest path is the demo orchestrator. It pulls prebuilt, signed images, runs the slim stack, seeds an alert, kicks off an investigation, and prints the URL of the resulting case in roughly 3-4 minutes on a warm Docker daemon.

pnpm aisoc:demo

Behind the scenes this runs docker compose -f docker-compose.demo.yml up -d against ghcr.io/beenuar/aisoc-* images (with pull_policy: missing, so re-runs don't re-pull). Stop it with:

pnpm aisoc:demo:down

If GHCR is unreachable on your network the orchestrator transparently falls back to a local build of every service.

To uninstall everything later (stack + volumes, optionally images, optionally node_modules and the repo clone), use the bundled uninstaller.

Development

docker compose up -d

This starts the full developer stack. Host-side ports are bound to 127.0.0.1 only by default (i.e. localhost-only) — adjust your reverse proxy or compose override if you need LAN access.

Application services

ServiceHost portContainer portNotes
api (FastAPI Core API)80008000OpenAPI at /docs
agents (LangGraph investigator)80018084
actions (SOAR executor)80028085
fusion (alert fusion + ML)80038003
threatintel80058005
purple-team (adversary emulation)80068006
ueba (user behavior analytics)80078004
honeytokens (deception platform)80088005
slack-bot (ChatOps)80098089profiles: [slack]
ingest-worker (Go OCSF normaliser)8081 / 90908080 / 9090HTTP + Prometheus metrics
enrichment (Go enrichment fan-out)80808082
realtime (Node WS + Web Push)80864000
connectors (50-vendor poller)80888003profiles: [connectors]
osquery-tls (host telemetry server)80918007profiles: [osquery]
web (Next.js console + Responder PWA)30003000

mcp (the Model Context Protocol stdio server) runs without a port — it is launched on demand by IDE-side agents (Claude Code, Cursor, Continue, Cody) over stdio.

Profile-gated services

connectors, osquery-tls, and slack-bot live behind Docker Compose profiles so the default dev stack stays light. Enable them with:

COMPOSE_PROFILES=connectors,osquery,slack docker compose up -d

Data-plane services

ServiceHost portNotes
postgres5432Cases, alerts, RBAC, vault
redis6379Sessions, rate limiting, agent cache
kafka9092Event spine
kafka-ui8090Web UI for the Kafka cluster
clickhouse8123 / 9000Analytical telemetry store
opensearch9200Full-text + log search
qdrant6333Vector store (RAG over runbooks + ATT&CK)
neo4j7474 / 7687Investigation graph
prometheus9091Metrics scraper
grafana3001Pre-wired dashboards (admin / admin)

Production

Use the production compose file:

docker compose -f docker-compose.prod.yml up -d

Before going live, walk through the Hardening Runbook — TLS termination, secret rotation, network policies, audit log forwarding, and tenant-scoped backups all need to be in place.

Environment variables

Copy .env.example to .env and fill in every required value before starting. See Environment Variables for the full reference.

Building images

# Build all service images
docker compose build

# Build a single service
docker compose build agents

For releases, prebuilt and signed images are published to GHCR:

ghcr.io/beenuar/aisoc-api:<version>
ghcr.io/beenuar/aisoc-agents:<version>
ghcr.io/beenuar/aisoc-actions:<version>
ghcr.io/beenuar/aisoc-fusion:<version>
ghcr.io/beenuar/aisoc-threatintel:<version>
ghcr.io/beenuar/aisoc-ueba:<version>
ghcr.io/beenuar/aisoc-honeytokens:<version>
ghcr.io/beenuar/aisoc-purple-team:<version>
ghcr.io/beenuar/aisoc-connectors:<version>
ghcr.io/beenuar/aisoc-osquery-tls:<version>
ghcr.io/beenuar/aisoc-slack-bot:<version>
ghcr.io/beenuar/aisoc-realtime:<version>
ghcr.io/beenuar/aisoc-mcp:<version>
ghcr.io/beenuar/aisoc-ingest:<version>
ghcr.io/beenuar/aisoc-enrichment:<version>
ghcr.io/beenuar/aisoc-web:<version>

Image provenance

Each image is signed with Cosign using keyless OIDC signatures issued through GitHub Actions. Verify any release artifact before deploying it into a sensitive environment:

cosign verify \
--certificate-identity-regexp '^https://github.com/beenuar/AiSOC' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
ghcr.io/beenuar/aisoc-api:<version>

The certificate identity is bound to this repository's workflow, so a successful verification proves the image was produced by the official release pipeline and has not been tampered with in transit.

Health checks

Every service exposes the same GET /healthz shape:

curl http://localhost:8000/healthz
# {"status": "ok", "version": "<version>"}

A quick "is everything up" sweep across the application tier:

for port in 8000 8001 8002 8003 8005 8006 8007 8008 8081 8080 8086; do
printf "%-5s " "$port"
curl -fsS "http://localhost:${port}/healthz" || echo "FAIL"
done

Logs

docker compose logs -f agents
docker compose logs -f api
docker compose logs -f realtime
docker compose logs -f ingest-worker

Reference

The canonical service inventory is in docker-compose.yml. The deeper architectural picture — what each service owns, how the data plane fits together, and where ITSM / Slack / osquery bolt in — lives in Architecture and the System Design doc.