Skip to content

Run the open-core stack with Docker Compose

Start tapes, PostgreSQL, Ollama, and the skills, search, and export cassettes from the source repository.

The tapes source repository includes a docker-compose.yaml for running the full open-core stack. Use this path when you need to develop or test tapes and its cassettes together. For everyday capture and search, the smaller tapes local up quickstart is enough.

You need Git, Docker with Compose, and tapesctl on your PATH.

Clone the repository:

Terminal window
git clone https://github.com/papercomputeco/tapes.git
cd tapes

Start everything:

Terminal window
docker compose up --build -d

The Compose file builds tapes core from the checkout and starts published images for the skills, search, and export cassettes. It also starts PostgreSQL and Ollama. PostgreSQL must pass its health check before the dependent services start.

On a fresh machine, pull the models the cassettes call. Nothing pulls them for you, and each cassette fails with an Ollama model-not-found error until its model is present:

Terminal window
docker compose exec ollama ollama pull embeddinggemma
docker compose exec ollama ollama pull llama3.2

embeddinggemma is the search cassette’s default embedding model. llama3.2 is the skills cassette’s default when CASSETTE_LLM_PROVIDER is ollama. The Compose file mounts ~/.ollama, so Docker reuses both on later runs.

llama3.2 is a 3B model, and it shows in the output: skill generation returns well-formed but generic skills, because the cassette asks Ollama for JSON and gets valid JSON regardless of how well the model read the session. For skills worth keeping, pull a larger model and point the cassette at it:

Terminal window
docker compose exec ollama ollama pull granite4.1:8b
docker-compose.yaml
skills:
environment:
CASSETTE_LLM_MODEL: granite4.1:8b

Any Ollama model works. granite4.1:8b is a reasonable default: 5.3GB, and tuned for the structured extraction this cassette does. CASSETTE_LLM_PROVIDER also takes openai and anthropic if you would rather spend a key than disk.

tapesctl names the read API and the ingest API separately, and already defaults to the two ports this stack publishes. Set them once to make every later command flag-free:

Terminal window
docker compose ps
tapesctl config set api-url http://localhost:8081
tapesctl config set ingest-url http://localhost:8082
tapesctl sessions list

Every service should be running. PostgreSQL should report healthy.

Capture a Claude Code session through the private ingest API, then read it back through the read API:

Terminal window
tapesctl start claude
tapesctl sessions list

Core admits each cassette’s OpenAPI document and republishes its API under /v1/cassettes/<name> on the read API. That is what this stack adds over the quickstart, and it is worth confirming before you rely on it:

Terminal window
tapesctl cassettes

All three should be listed. If none are, read docker compose logs tapes for a rejected document.

Search runs over the embedded span projection:

Terminal window
tapesctl search "how was authentication fixed?"

Export writes a session’s bundle as JSONL:

Terminal window
tapesctl export <session-id> -o session.jsonl

Skills have no built-in verb. tapesctl generates a subcommand per cassette from the server’s own OpenAPI document, with one method per operation, so the skills surface comes from the running cassette rather than from the client:

Terminal window
tapesctl cassettes skills --help
tapesctl cassettes skills generate-skill

The stack binds every published port to 127.0.0.1. tapesctl and any other client use 8081 and 8082 only; a cassette’s own port is there for inspecting that one service in isolation:

Port Service Use
5432 PostgreSQL Local database access
11434 Ollama Chat and embedding requests
8080 tapes proxy OpenAI- and Anthropic-compatible traffic
8081 tapes read API tapesctl read commands
8082 tapes ingest API Agent capture and transcript sync
9999 skills cassette The cassette’s own listener, for debugging it directly
9998 search cassette The cassette’s own listener, for debugging it directly
9997 export cassette The cassette’s own listener, for debugging it directly
Terminal window
docker compose down

This preserves the named PostgreSQL and tapes volumes. To inspect a startup failure before stopping the stack, run docker compose logs <service>, where <service> is tapes, postgres, ollama, skills, search, or export.