Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/joseluis-dev/harness-ai/llms.txt

Use this file to discover all available pages before exploring further.

Harness AI is composed of a set of Docker services that are introduced incrementally across deployment phases. From the very first commit, the topology enforces a strict boundary between the single public-facing service (harness-core) and everything else, which lives on a private Docker network. Understanding this map is a prerequisite before configuring environment variables or deploying to Dokploy.

Services by Deployment Phase

The table below lists every service in the system, the network it belongs to, and the phase in which it is introduced.

Phase 0 + Phase 0.b — Base Executable

These services form the entire stack required to run the harness locally and in production through Phase 0.b.
ServiceRoleNetwork
harness-coreAstro SSR BFF — the only publicly-exposed servicepublic-net + private-harness-net
admin-panelInternal admin UI — IP/VPN-allowlisted onlyprivate-harness-net
mcp-auth-serviceCentralised OAuth 2.0 authorisation serverprivate-harness-net
postgresBusiness database (harness_db) — executions, audit, RAGprivate-harness-net
postgres-authAuth database (harness_auth_db) — OAuth clients, tool registry, permissionsprivate-harness-net
redisRQ broker and operational cacheprivate-harness-net
minioObject storage for ingested documents (optional until Phase 4)private-harness-net
mcp-readonly-sqlMCP server — read-only SQL access via harness_dbprivate-harness-net
mcp-identity-connectorIdentity sidecar — resolves actor context from external IdPprivate-harness-net
model-gatewayLLM gateway — all inference traffic is routed through hereprivate-harness-net
vllmLocal vLLM inference backendprivate-harness-net

Phase 4–5 — Document Ingestion

These services are added when the document-watcher and RAG pipeline are activated.
ServiceRoleNetwork
document-watcherWatches a directory for new or changed filesprivate-harness-net
document-workerProcesses ingestion jobs from the watcher queueprivate-harness-net
embedding-workerGenerates vector embeddings for ingested documentsprivate-harness-net
mcp-document-registryMCP server — exposes document registry to the agentprivate-harness-net

Phase 7+ — Advanced Automation

These services are introduced in later phases and all require additional security controls before activation.
ServiceRoleNetwork
langgraph-workerStateful multi-step agent runnerprivate-harness-net
n8nWorkflow automation — activated only behind VPN or reverse proxyprivate-harness-net
mcp-expedientesMCP server for institutional case-file integrationprivate-harness-net
mcp-reportesMCP server for institutional report integrationprivate-harness-net
mcp-notificacionesMCP server for notification dispatchprivate-harness-net
observabilityMetrics, tracing, and log aggregation stackprivate-harness-net

Network Topology

Harness AI uses two Docker networks to enforce isolation at the infrastructure level.
public-net:
  - harness-core          ← ONLY service reachable from the outside

private-harness-net:
  - admin-panel
  - mcp-auth-service
  - postgres
  - postgres-auth
  - redis
  - minio
  - model-gateway
  - vllm
  - runtime-python
  - mcp-* services
  - document-worker
  - embedding-worker
  - langgraph-worker
The public-netprivate-harness-net separation is enforced from Phase 0. Any service other than harness-core that appears on public-net is a deployment violation and must be corrected before a release can proceed.

Exposure Rules

Only one service is ever publicly exposed:
harness-core          ← bound to :4321; TLS terminated by Dokploy / reverse proxy
The following services must never be reachable from the public internet:
admin-panel           ← internal only; IP/VPN allowlist required
mcp-auth-service
postgres
postgres-auth
redis
vllm
model-gateway
runtime-python
mcp-* servers
minio (without access controls)
n8n may only be exposed if protected by all of the following: a VPN or reverse proxy, strong authentication, and an IP allowlist where applicable. It is not part of the MVP and is introduced no earlier than Phase 7.
admin-panel must never be placed on public-net. It is an internal administration interface and must only be reachable via VPN, a jump host, or an IP-allowlisted reverse proxy. Exposing it publicly is a critical security violation regardless of authentication controls placed in front of it.
minio is optional through Phase 3. The object store is only required once the document ingestion pipeline (Phase 4) is activated. You can omit the minio service entirely from your compose configuration until that point without affecting any Phase 0–3 acceptance criteria.

Dockerfile Locations

Each deployable service has its own Dockerfile under infra/docker/. The table below lists the files that exist in the repository for the Phase 0 + Phase 0.b services.
ServiceDockerfile
harness-coreinfra/docker/Dockerfile.harness-core
runtime-pythoninfra/docker/Dockerfile.runtime-python
model-gatewayinfra/docker/Dockerfile.model-gateway
mcp-identity-connectorinfra/docker/Dockerfile.mcp-identity-connector

Docker Invariants

The following rules apply to every image and compose configuration in the repository.
  • No hardcoded secrets in images. No client_secret, database password, or API key is written into any Dockerfile or baked into an image layer. All sensitive values are injected at runtime by the Dokploy secrets manager or the host environment.
  • All values injected via Dokploy secrets/env. The compose files read every variable from the environment using ${VARIABLE_NAME} interpolation. No defaults are provided for secret fields in the production compose file; missing values cause docker compose up to fail immediately.
  • harness_db and harness_auth_db are always separate clusters. The two PostgreSQL instances run as distinct compose services (postgres and postgres-auth) with different credentials and different named volumes. They may share the same PostgreSQL binary, but they must never share the same database instance. tool_registry lives in harness_auth_db because it defines technical authorisation state (scopes, risk_level, permissions); any copy in harness_db is a read-only cache derivative.
  • mcp-readonly-sql connects only to harness_db using a readonly PostgreSQL user. It must never be given a connection string pointing at harness_auth_db.

Health Check Pattern

Every service in the compose files declares an explicit Docker healthcheck. The pattern for Python-based services uses a stdlib one-liner rather than wget (which is absent from python:3.12-slim):
healthcheck:
  test:
    - "CMD-SHELL"
    - "python -c \"import urllib.request,sys; r=urllib.request.urlopen('http://127.0.0.1:8000/healthz',timeout=2); sys.exit(0 if r.status==200 else 1)\""
  interval: 5s
  timeout: 3s
  retries: 10
  start_period: 15s
PostgreSQL containers use pg_isready:
healthcheck:
  test: ["CMD-SHELL", "pg_isready -U harness -d harness_db"]
  interval: 10s
  timeout: 5s
  retries: 5
  start_period: 30s
Redis uses the native CLI ping:
healthcheck:
  test: ["CMD", "redis-cli", "ping"]
  interval: 10s
  timeout: 3s
  retries: 5
The harness-core depends on postgres and redis reaching service_healthy before it starts. Services such as mcp-identity-connector and model-gateway use service_started in depends_on to avoid circular dependency chains.

Build docs developers (and LLMs) love