RememberStackremember.dev/docs

Install with Docker Compose

This page takes you from an empty machine to a running RememberStack that has read its first document. It uses the compose.yaml and .env.example that ship in the repository. Check Requirements first.

1. Get the files

git clone https://github.com/writeitai/remember-stack.git
cd remember-stack
git checkout v0.17.2
cp .env.example .env
printf 'REMEMBERSTACK_POSTGRES_PASSWORD=%s\nREMEMBERSTACK_MINIO_ACCESS_KEY=%s\nREMEMBERSTACK_MINIO_SECRET_KEY=%s\nREMEMBERSTACK_SELFHOST_DEPLOYMENT_ID=%s\n' \
  "$(openssl rand -hex 32)" "$(openssl rand -hex 12)" "$(openssl rand -hex 32)" \
  "$(openssl rand -hex 16 | sed -E 's/^(.{8})(.{4}).(.{3}).(.{3})(.{12})$/\1-\2-4\3-8\4-\5/')" >> .env

The last command generates the database password, the object-store credentials and the deployment id (a random UUID); .env.example ships none of them, and Compose refuses to start without them.

Checking out a release tag keeps compose.yaml in step with the image tag it names (ghcr.io/writeitai/remember-stack:0.17.2). Each GitHub release also attaches compose.yaml and .env.example. GitHub renames the second one on download, so it appears as default.env.example.

2. Fill in .env

Docker Compose reads .env from the project directory, substitutes its values into compose.yaml and passes every variable in it to the engine containers. These variables have no default in compose.yaml and must be set:

VariableWhat to put there
REMEMBERSTACK_OPENROUTER_API_KEYYour OpenRouter API key. The placeholder lets the stack start, but every model call fails with it.
REMEMBERSTACK_SELFHOST_DEPLOYMENT_IDThis deployment's id, a random UUID generated in step 1.
REMEMBERSTACK_SELFHOST_DEPLOYMENT_SLUGA short name, such as billing-team.
REMEMBERSTACK_SELFHOST_DEPLOYMENT_NAMEA display name, such as Billing team memory.
REMEMBERSTACK_SELFHOST_API_PORTThe host port for the API. 8000 in the example. Compose publishes it on 127.0.0.1 only; see Before you expose it.
REMEMBERSTACK_POSTGRES_USER, REMEMBERSTACK_POSTGRES_PASSWORD, REMEMBERSTACK_POSTGRES_DBDatabase credentials; the password is generated in step 1. PostgreSQL creates them on first start.
REMEMBERSTACK_MINIO_ACCESS_KEY, REMEMBERSTACK_MINIO_SECRET_KEYObject-store credentials, generated in step 1. The bundled SeaweedFS store uses them as its only S3 identity; Compose refuses to start if either is empty.

3. Start the stack

docker compose up -d --wait

On the first run Compose builds the PostgreSQL image (it compiles the pg_textsearch extension, which takes a few minutes), pulls SeaweedFS and the RememberStack image, and starts everything in dependency order:

  1. postgres and object-store start and report healthy.
  2. setup runs the database migrations, creates the three buckets, records the deployment, installs the assured operations and the example saved queries, and exits.
  3. api and the twelve workers start once setup has exited successfully.

--wait returns when the services are running and healthy.

What each service does

ServiceCommandRole
postgrespostgresPostgreSQL 19 beta with the extensions RememberStack needs. It holds every document, version, claim, fact and entity, and the work queue.
object-storeserver -s3SeaweedFS, S3-compatible storage for original files, converted Markdown and snapshots. Reachable only by the other containers; no host port is published.
setupsetupOne-shot: migrations, buckets, the deployment row, seed data. Runs again, harmlessly, on every up.
apiapiThe HTTP API on port 8000 inside the container, published on 127.0.0.1:REMEMBERSTACK_SELFHOST_API_PORT.
worker-convertworker --stage convertTurns an uploaded file into Markdown using the configured converter.
worker-structureworker --stage structureFinds the document's sections and writes section summaries.
worker-chunkworker --stage chunkSplits the document into chunks.
worker-embed-chunkworker --stage embed_chunkEmbeds chunks for semantic search.
worker-extract-claimsworker --stage extract_claimsReads each chunk and selects the sentences that state something.
worker-ground-claimsworker --stage ground_claimsTurns those sentences into claims (what the source said), each tied to its passage.
worker-normalize-relationsworker --stage normalize_relationsResolves entities and turns claims into relations and facts.
worker-adjudicate-observationsworker --stage adjudicate_observationsDecides, entity by entity, whether a new statement confirms, contradicts or replaces a fact the memory holds.
worker-adjudicate-supersessionworker --stage adjudicate_supersessionRecords the follow-up of those decisions for the version and refreshes affected entity profiles.
worker-embed-claimworker --stage embed_claimEmbeds claims for semantic search.
worker-reconcileworker --stage reconcileSettles the version's lifecycle once the other stages are done.
worker-label-relationworker --stage label_relationWrites the searchable label of each relation and embeds facts for semantic search.
projectionsproject --plane p3Profile operations only. Builds a filesystem view snapshot on demand.

Each worker handles one stage and wakes when new work for that stage is committed. The pipeline and readiness explains what the stages produce.

4. Check that it is healthy

docker compose ps
curl http://localhost:8000/healthz

/healthz answers {"status":"ok"} when the API can reach PostgreSQL. It is the check Compose itself uses, and it never needs a token.

curl http://localhost:8000/deployment

/deployment reports the source revision the image was built from (build_revision, empty for a locally built image) and the model bound to each pipeline seat (model_bindings).

5. Send a first document

Install the client on the machine you work from. It needs Python 3.12 or later.

pip install remember
export REMEMBER_API_URL=http://localhost:8000

Save this as standup.md:

# Stand-up, 17 September 2026
 
Ravi said the billing migration moves from June to October, because the
invoice exporter needs a rewrite. Dana agreed and will tell finance.
Ravi owns the invoice exporter.

Send it and ask about it:

remember ingest standup.md \
  --source-kind file --source-ref notes/standup.md \
  --source-modified-at 2026-09-17T09:30:00+00:00
 
remember query "Who owns the invoice exporter?"

remember ingest prints the new version_id. Processing takes minutes, so a query sent straight away may find nothing yet. Wait until a document is queryable shows how to wait for a version. To watch the work happen:

docker compose logs -f worker-extract-claims worker-normalize-relations

Note

Set REMEMBER_API_URL explicitly, or run remember setup --self-hosted, which stores the address. With no address anywhere, the CLI falls back to http://127.0.0.1:8000.

Stop, start and reset

ToRunData
Stop the containersdocker compose stopKept
Start them againdocker compose start or docker compose up -dKept
Remove the containersdocker compose downKept in the volumes
Remove everything, including all memorydocker compose down -vDeleted

Volumes

Compose names volumes after the project, rememberstack:

VolumeMounted atHolds
rememberstack_postgres-data/var/lib/postgresql in postgresThe database: every document, version, claim, fact and entity, the work queue and the cost ledger
rememberstack_object-store-data/data in object-storeOriginal files, converted Markdown, derived artifacts and filesystem snapshots
rememberstack_app-state/var/lib/rememberstack in the app containersWorking directories; the optional debug capture of invalid model output
rememberstack_forget-manifests/var/lib/rememberstack/forget-manifests in the app containersHard-forget manifests. Empty in a Compose deployment.

The first two hold the memory. Back them up together; see Upgrades and migrations.

Before you expose it

By default the API needs no token, so Compose publishes its port on 127.0.0.1 only: only this machine can reach it. That holds on Docker Engine 28.0.0 or later. On an older engine, other hosts on the same local network can reach a port published on 127.0.0.1, so set REMEMBERSTACK_SELFHOST_API_BEARER_TOKEN and REMEMBERSTACK_SELFHOST_REQUIRE_API_AUTH=true before the first start (see Requirements). To serve other machines, set a token and then the address to publish on (REMEMBERSTACK_SELFHOST_API_PUBLISH_ADDRESS); see Opening the API to other machines.