Summary
This is part of Chronos tutorial series.
Chronos by Intelligex is an open source, self-hosted control plane for AI agents and MCP tools. It runs as a single container, but real deployments rarely stop there — you want a real database, horizontal scale via a Redis-backed queue, an OpenTelemetry pipeline, schedules, or a local vector store for RAG.
The repository ships a set of opinionated docker-compose recipes, each demonstrating one production-shaped setup. This tutorial walks through every recipe, what it adds, and when to use it. You can use the same files for local development or as a starting point for production hosting on a Linux server.
Prerequisites
- Docker and Docker Compose installed.
- Git.
- Local Chronos image — see the Chronos self-hosted quickstart if you have not done this before. Every recipe below consumes
chronos:local.
Build the local image
Every compose recipe expects a locally-tagged image named chronos:local. Build it once:
git clone git@github.com:intelligexhq/chronos.git
cd chronos/chronos_app/docker
# inventory of compose recipes
ls -1 *.yml
# docker-compose.yml
# docker-compose-workers.yml
# docker-compose-vectordb.yml
# docker-compose-schedules.yml
# docker-compose-opentelemetry.yml
# build the all-in-one local image
docker build -f Dockerfile.local -t chronos:local ..
All five recipes live next to Dockerfile.local.
The examples/ subdirectory adds an end-to-end demo + smoke test that exercises the Chronos Agent Registry (since v1.6) and MCP Gateway — covered in its own section below.
Data stores
Chronos has built-in support for industry battle tested relational backends, selected via environment variable:
- SQLite (default; dev, testing).
- PostgreSQL (recommended for production).
If you supply nothing, Chronos uses a SQLite file at ~/.chronos/database.sqlite. To switch, set the DATABASE_* variables on the Chronos container:
DATABASE_TYPE # sqlite | postgres (defaults to sqlite)
DATABASE_PATH # SQLite only — directory holding database.sqlite
DATABASE_HOST # Postgres
DATABASE_PORT # 5432 (postgres)
DATABASE_NAME
DATABASE_USER
DATABASE_PASSWORD
Compose recipes below either uses SQLite or wires a Postgres service alongside Chronos with the variables already set.
Recipe 1 — single Chronos service with Postgres
docker-compose.yml is the minimum sensible production-shaped stack: one Chronos container talking to one Postgres container, with the initial admin user pre-provisioned via CHRONOS_INITIAL_USER.
docker compose -f docker-compose.yml up
# Chronos is now accessible on http://localhost:3001
docker compose down
Use this when you want Postgres-backed persistence on a single host. Scale beyond one Chronos instance, and you will want recipe 2.
Recipe 2 — workers and queue mode
docker-compose-workers.yml runs Chronos in queue / worker mode: one main service handles HTTP traffic, one or more worker instances pull jobs from a Redis-backed BullMQ queue. PostgreSQL still backs the relational layer.
# start with one main + one worker
docker compose -f docker-compose-workers.yml up
# scale the worker pool to three instances
docker compose -f docker-compose-workers.yml up --scale chronos-worker=3
# Chronos is on http://localhost:3001
# BullMQ dashboard (if enabled) on http://localhost:3001/admin/queues
Use this when one Chronos instance can no longer keep up with agent invocations, or when you want to isolate request handling from long-running execution.
Recipe 3 — vector database with locally-hosted models
docker-compose-vectordb.yml adds Qdrant for vector search and Ollama for locally-hosted embedding (and inference) models. Pair this recipe with the build a RAG agent with Qdrant and Ollama tutorial.
docker compose -f docker-compose-vectordb.yml up
# pull an embedding model into the Ollama container after startup
docker compose -f docker-compose-vectordb.yml exec ollama ollama pull nomic-embed-text
# Chronos: http://localhost:3001
# Configure Vector Store in UI: http://qdrant:6333
# Configure Embeddings in UI: http://ollama:11434
Use this when you want a fully self-hosted RAG stack — no third-party embedding API calls, no managed vector DB.
Recipe 4 — schedules
docker-compose-schedules.yml boots Chronos with ENABLE_SCHEDULES=true and MODE=queue, plus Postgres and Redis. The scheduler swaps from the in-process variant to the queue-backed BullMQ scheduler, which is the right shape for any deployment with more than one Chronos replica.
docker compose -f docker-compose-schedules.yml up
# add a schedule from the UI: Schedules → + Add Schedule
The companion how-to is schedule agent runs in Chronos by Intelligex.
Recipe 5 — OpenTelemetry observability
docker-compose-opentelemetry.yml wires Chronos into a standard OTel collector + tracing-backend stack so spans, metrics, and logs flow into the same place as the rest of your platform telemetry.
docker compose -f docker-compose-opentelemetry.yml up
# Chronos: http://localhost:3001
# Backend UI: check the compose file — varies by backend
Use this when you have an existing OTel pipeline and want Chronos traces alongside everything else.
End-to-end demo: Agent Registry + MCP Gateway
The repository also ships a turnkey demo at chronos_app/docker/examples/ that exercises the Agent Registry and MCP Gateway end-to-end. Two compose files live there:
docker-compose.yml— Chronos + Postgres + a tiny Streamable-HTTP MCP server + a minimal TypeScript HTTP agent example.docker-compose.smoke.yml— non-interactive smoke test that registers this small MCP server + an HTTP agent, exercises the full callback round-trip, and asserts the result. Used in CI; useful as a "is everything wired?" sanity check after upgrades.
# end-to-end interactive demo
cd chronos_app/docker/examples
docker compose up
# automated smoke test
docker compose -f docker-compose.smoke.yml up \
--build --abort-on-container-exit --exit-code-from smoke-runner
The companion tutorials walk through the demo step by step:
Next steps
- Build something on top. Recipes 3 and 4 each have a companion how-to — RAG and schedules respectively.
- Pick a database. SQLite is fine for local; Postgres is the right default for anything else.
- Add observability. Recipe 5 is the production-grade path; structured logs land in
~/.chronos/logseither way. - Layer on the agent + MCP demo. Once Chronos is up, the end-to-end demo is the fastest way to see the full Chronos control plane in action.