Skip to content

Run in Docker

You can run the headless engine (src/node/service.ts) in a container, on any machine that runs Docker, such as a virtual private server (VPS), a network-attached storage (NAS) device or a Linux server. This page shows how to:

  • Start the engine and find its token
  • Set up file watching and permissions
  • Open network access and connect agents

Build the engine first, then start the container with Docker Compose:

  1. Build the service from the repository root:

    Terminal window
    npm run build:service
  2. Start the container on your vault folder:

    Terminal window
    DATANOTES_VAULT=your_vault_folder docker compose \
    -f deploy/docker/docker-compose.yml up -d --build

The container mounts your vault folder at /vault, and its entrypoint starts the engine with --vault /vault. The database is then a folder inside the vault, datanotes/ for a new database. A folder that holds metastore.yaml at its root works too: the engine then finds the database at the vault root. Use Datanotes with Obsidian explains both setups. The first start creates the settings file, /config/settings.json, in the datanotes-config volume, with port 27150 and a random owner token. The settings reference lists every key you can set there, such as semantic search and logs.

The engine keeps its store outside the vault: the journal, the history of your tables, the named tokens, the change feed and the logs. In the container, the store is /data/<database id>/, in the datanotes-data volume. The image sets DATANOTES_DATA_HOME=/data. Keep that volume: without it, a new container starts with an empty journal and no history.

The owner token is in the settings file inside the container. Print it with:

Terminal window
docker compose -f deploy/docker/docker-compose.yml \
exec datanotes cat /config/settings.json

The owner token gives full access. Keep it for administration, and create a named token for each agent, program or device.

Programs such as a task planner or your own agent run as their own containers or processes. Each one gets its own token from POST /datanotes/tokens/create/ and reaches the engine over HTTP. Build on Datanotes explains the ways to build on the engine.

The container polls the vault for changes every 3s, because DATANOTES_WATCH defaults to poll. Bind mounts from Windows and macOS hosts deliver no file events, so polling is the only option there. On a Linux host, set DATANOTES_WATCH=events to react to changes as they happen.

Polling a large vault over a bind mount is slow: one scan of 10,000 notes takes seconds. The engine then scans less often, so a change you make on the host shows later. On Windows and macOS, keep a large vault on a Linux volume instead, and set DATANOTES_WATCH=events. Limits shows the compose file and the times we measured.

Run one engine per database folder. The engine holds a lock file, engine.lock, in its store, so it refuses only a second engine with the same store. The container keeps its store in its own volume. An engine on the host has another store, so it starts on the same folder, and the two engines lose each other’s writes.

Never run the engine on the host and the engine in Docker on the same folder. Stop the host engine with datanotes stop before you start the container. Sync the vault between devices explains the same rule for a synced vault.

Give the container write access to the vault

Section titled “Give the container write access to the vault”

The container runs as the user engine, and the engine writes notes in the vault. On its first start it also writes the database’s id into metastore.yaml. Make the vault folder writable by that user in one of two ways:

  • Add a user: entry to the compose file with the owner of the folder
  • Change the folder’s owner with chown

The compose file publishes the port on 127.0.0.1 only. To reach the engine from outside, put a reverse proxy or a tunnel in front of it. The security page explains what to expose and which tokens to use.

Agents reach the engine through the Model Context Protocol (MCP) server. Run it next to the engine:

Terminal window
npx -y datanotes mcp serve --url http://127.0.0.1:27150

Connect agents explains how to point your agents at it.