Skill Tracer
Skills › Scientific Agent Skills › open-notebook › configuration.md

configuration.md

180 lines · skills/open-notebook/references/configuration.md at 5f2bc03

Open on GitHub
1# Open Notebook Configuration Guide
2
3Reviewed against [v1.14.0 Compose](https://github.com/lfnovo/open-notebook/blob/v1.14.0/docker-compose.yml),
4[current environment reference](https://github.com/lfnovo/open-notebook/blob/3127f14ea9dbb519f0e4ddc64a0742ca644ba6ef/docs/5-CONFIGURATION/environment-reference.md),
5and [source installation](https://github.com/lfnovo/open-notebook/blob/v1.14.0/docs/1-INSTALLATION/from-source.md)
6on 2026-09-30. Commands below are illustrative deployment examples; no containers
7or authenticated provider calls were launched for this review.
8

Open Notebook Configuration Guide

Reviewed against v1.14.0 Compose, current environment reference, and source installation on 2026-09-30. Commands below are illustrative deployment examples; no containers or authenticated provider calls were launched for this review.

Raw lines 1 to 8
9## Docker deployment and persistence
11Use the upstream `docker-compose.yml`, which has services **`surrealdb`** and
12**`open_notebook`**, rather than substituting an unverified image location. The
13reviewed application image is `lfnovo/open_notebook:v1-latest`, and the database
14image is `surrealdb/surrealdb:v2`. Record resolved image digests for reproducibility;
15these tags can change. Do not replace the database with an arbitrary `latest` major.
17```bash
18curl --fail --location --output docker-compose.yml \
19 https://raw.githubusercontent.com/lfnovo/open-notebook/v1.14.0/docker-compose.yml
20```
22The downloaded file contains a **literal** encryption-key placeholder. Replace it
23in the file, or change that environment entry to
24`OPEN_NOTEBOOK_ENCRYPTION_KEY=${OPEN_NOTEBOOK_ENCRYPTION_KEY:?Set a key}` and supply
25the variable through your deployment's secret mechanism. A shell export alone
26cannot override a literal Compose environment entry. Add the password to the
27application environment if authentication is needed; it is not in the default
28Compose application environment automatically.
30```bash
31docker compose up -d
32docker compose logs --tail=100 open_notebook
33docker compose stop
34```
36Application UI/API ports are 8502/5055. For a local-only installation bind them to
37`127.0.0.1`; use HTTPS and authenticated access when operating remotely. The upstream
38SurrealDB debug port binds to loopback, while the application reaches it on the
39Compose network. Use matching database credentials for both services.
41Persistent mounts in this file are:
43| Host directory | Container path | Content |
44| --- | --- | --- |
45| `./surreal_data` | `/mydata` | SurrealDB data using RocksDB |
46| `./notebook_data` | `/app/data` | Uploads, podcasts, SQLite chat checkpoints, runtime caches |
48The source uses `./data/uploads`, not an `UPLOAD_DIR=/app/uploads` configuration.
49Preserving only uploads loses podcast files and chat checkpoints.

Docker deployment and persistence

Use the upstream docker-compose.yml, which has services **surrealdb and open_notebook**, rather than substituting an unverified image location. The reviewed application image is lfnovo/open_notebook:v1-latest, and the database image is surrealdb/surrealdb:v2. Record resolved image digests for reproducibility; these tags can change. Do not replace the database with an arbitrary latest major.

curl --fail --location --output docker-compose.yml \
  https://raw.githubusercontent.com/lfnovo/open-notebook/v1.14.0/docker-compose.yml

The downloaded file contains a literal encryption-key placeholder. Replace it in the file, or change that environment entry to OPEN_NOTEBOOK_ENCRYPTION_KEY=${OPEN_NOTEBOOK_ENCRYPTION_KEY:?Set a key} and supply the variable through your deployment's secret mechanism. A shell export alone cannot override a literal Compose environment entry. Add the password to the application environment if authentication is needed; it is not in the default Compose application environment automatically.

docker compose up -d
docker compose logs --tail=100 open_notebook
docker compose stop

Application UI/API ports are 8502/5055. For a local-only installation bind them to 127.0.0.1; use HTTPS and authenticated access when operating remotely. The upstream SurrealDB debug port binds to loopback, while the application reaches it on the Compose network. Use matching database credentials for both services.

Persistent mounts in this file are:

Host directoryContainer pathContent
./surreal_data/mydataSurrealDB data using RocksDB
./notebook_data/app/dataUploads, podcasts, SQLite chat checkpoints, runtime caches

The source uses ./data/uploads, not an UPLOAD_DIR=/app/uploads configuration. Preserving only uploads loses podcast files and chat checkpoints.

Raw lines 9 to 50
51## Environment variables
53| Variable | Scope and meaning |
54| --- | --- |
55| `OPEN_NOTEBOOK_ENCRYPTION_KEY` | Server secret for stored provider credentials. Keep unchanged and back it up separately; it does not encrypt source documents. `_FILE` supports Docker secrets. |
56| `OPEN_NOTEBOOK_PASSWORD` | Optional server instance password. API uses `Authorization: Bearer <password>`. Authentication is disabled if unset. `_FILE` is supported server-side. |
57| `SURREAL_URL` | Compose connection `ws://surrealdb:8000/rpc`. |
58| `SURREAL_USER`, `SURREAL_PASSWORD` | Must match database service; local upstream defaults are root/root. `SURREAL_PASS` is not the variable. |
59| `SURREAL_NAMESPACE`, `SURREAL_DATABASE` | Upstream Compose values `open_notebook`. |
60| `API_URL` | Browser-visible backend location when configured. Do not use a container-only hostname here for remote browsers. |
61| `INTERNAL_API_URL` | Backend used by Next.js server-side proxying; default localhost:5055 in the combined container. |
62| `OPEN_NOTEBOOK_MAX_UPLOAD_SIZE_MB` | Server body limit, default 100; a reverse proxy may impose a smaller limit. |
63| `OPEN_NOTEBOOK_WORKER_MAX_TASKS` | Worker concurrency, default 5; set in worker process/container environment. |
64| `OPEN_NOTEBOOK_ENABLE_DOCLING` | Optional heavy document/OCR runtime; default false, first start downloads dependencies. |
65| `OPEN_NOTEBOOK_ENABLE_CRAWL4AI` | Optional local crawling runtime; default false. |
67The bundled Python **client helpers** additionally read `OPEN_NOTEBOOK_URL`
68(default backend `http://localhost:5055`) and `OPEN_NOTEBOOK_PASSWORD`. They do not
69need database credentials or the encryption key. `OPEN_NOTEBOOK_URL` is a helper
70setting, not a replacement for the server's `API_URL`.
72Provider key environment variables such as `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`,
73`GOOGLE_API_KEY`, and `GROQ_API_KEY` remain legacy fallbacks. Upstream now deprecates
74that mechanism; configure stored credentials through **Manage → Models** or the
75credential API for new automation.

Environment variables

VariableScope and meaning
OPEN_NOTEBOOK_ENCRYPTION_KEYServer secret for stored provider credentials. Keep unchanged and back it up separately; it does not encrypt source documents. _FILE supports Docker secrets.
OPEN_NOTEBOOK_PASSWORDOptional server instance password. API uses Authorization: Bearer <password>. Authentication is disabled if unset. _FILE is supported server-side.
SURREAL_URLCompose connection ws://surrealdb:8000/rpc.
SURREAL_USER, SURREAL_PASSWORDMust match database service; local upstream defaults are root/root. SURREAL_PASS is not the variable.
SURREAL_NAMESPACE, SURREAL_DATABASEUpstream Compose values open_notebook.
API_URLBrowser-visible backend location when configured. Do not use a container-only hostname here for remote browsers.
INTERNAL_API_URLBackend used by Next.js server-side proxying; default localhost:5055 in the combined container.
OPEN_NOTEBOOK_MAX_UPLOAD_SIZE_MBServer body limit, default 100; a reverse proxy may impose a smaller limit.
OPEN_NOTEBOOK_WORKER_MAX_TASKSWorker concurrency, default 5; set in worker process/container environment.
OPEN_NOTEBOOK_ENABLE_DOCLINGOptional heavy document/OCR runtime; default false, first start downloads dependencies.
OPEN_NOTEBOOK_ENABLE_CRAWL4AIOptional local crawling runtime; default false.

The bundled Python client helpers additionally read OPEN_NOTEBOOK_URL (default backend http://localhost:5055) and OPEN_NOTEBOOK_PASSWORD. They do not need database credentials or the encryption key. OPEN_NOTEBOOK_URL is a helper setting, not a replacement for the server's API_URL.

Provider key environment variables such as OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEY, and GROQ_API_KEY remain legacy fallbacks. Upstream now deprecates that mechanism; configure stored credentials through Manage → Models or the credential API for new automation.

Raw lines 51 to 76
77## AI provider setup
79Use the UI to add a configuration, test it, discover models, and select models for
80registration. A provider supporting language models does not necessarily support
81embeddings, transcription, or speech. Inspect `/api/models/providers` and the
82chosen model's capabilities. Model/credential tests may invoke paid provider APIs.
84The following Python example is illustrative. Run from the skill's `scripts/`
85directory. It reads an existing provider secret from the environment only to submit
86it to the user's own Open Notebook credential store; it does not print the secret.
87Choose a **language-model name returned by discovery** before calling the function.
88Do not automatically register every discovered name as a language model.
90```python
91import os
92from _common import record_path, request_json
95def register_openai_language_model(selected_name):
96 credential = request_json("POST", "/credentials", json={
97 "name": "Research provider", "provider": "openai",
98 "api_key": os.environ["OPENAI_API_KEY"],
99 "modalities": ["language"],
100 })
101 credential_path = "/credentials/" + record_path(credential["id"])
102 check = request_json("POST", credential_path + "/test")
103 if not check["success"]:
104 raise RuntimeError(check["message"])
105 discovery = request_json("POST", credential_path + "/discover")
106 selected = next(
107 model for model in discovery["discovered"] if model["name"] == selected_name
108 )
109 registered = request_json("POST", credential_path + "/register-models", json={
110 "models": [{"name": selected["name"], "provider": selected["provider"],
111 "model_type": "language"}],
112 })
113 return credential["id"], registered
114```
116Discovery returns `discovered`, not `models`; those objects have names, not model
117record IDs. Registration returns counts, not IDs. Retrieve registered records with
118`GET /api/models?type=language` and choose the matching name, provider, and credential.
119Register a suitable embedding model separately. Explicitly assign defaults using
120`PUT /api/models/defaults`, for example `default_chat_model` and
121`default_embedding_model` with their registered IDs. `/api/models/auto-assign` fills
122only these two required slots and can select a cloud provider; review that selection.
123Speech and other optional slots need explicit assignment when desired.
125Deleting a credential without `migrate_to` also deletes its linked models; a failed
126connection test is not a reason to delete an existing credential automatically.

AI provider setup

Use the UI to add a configuration, test it, discover models, and select models for registration. A provider supporting language models does not necessarily support embeddings, transcription, or speech. Inspect /api/models/providers and the chosen model's capabilities. Model/credential tests may invoke paid provider APIs.

The following Python example is illustrative. Run from the skill's scripts/ directory. It reads an existing provider secret from the environment only to submit it to the user's own Open Notebook credential store; it does not print the secret. Choose a language-model name returned by discovery before calling the function. Do not automatically register every discovered name as a language model.

import os
from _common import record_path, request_json


def register_openai_language_model(selected_name):
    credential = request_json("POST", "/credentials", json={
        "name": "Research provider", "provider": "openai",
        "api_key": os.environ["OPENAI_API_KEY"],
        "modalities": ["language"],
    })
    credential_path = "/credentials/" + record_path(credential["id"])
    check = request_json("POST", credential_path + "/test")
    if not check["success"]:
        raise RuntimeError(check["message"])
    discovery = request_json("POST", credential_path + "/discover")
    selected = next(
        model for model in discovery["discovered"] if model["name"] == selected_name
    )
    registered = request_json("POST", credential_path + "/register-models", json={
        "models": [{"name": selected["name"], "provider": selected["provider"],
                    "model_type": "language"}],
    })
    return credential["id"], registered

Discovery returns discovered, not models; those objects have names, not model record IDs. Registration returns counts, not IDs. Retrieve registered records with GET /api/models?type=language and choose the matching name, provider, and credential. Register a suitable embedding model separately. Explicitly assign defaults using PUT /api/models/defaults, for example default_chat_model and default_embedding_model with their registered IDs. /api/models/auto-assign fills only these two required slots and can select a cloud provider; review that selection. Speech and other optional slots need explicit assignment when desired.

Deleting a credential without migrate_to also deletes its linked models; a failed connection test is not a reason to delete an existing credential automatically.

Raw lines 77 to 127
128## Ollama and local processing
130Use upstream's [Ollama Compose example](https://github.com/lfnovo/open-notebook/blob/v1.14.0/examples/docker-compose-ollama.yml)
131for a matching network and volume definition. A provider URL such as
132`http://ollama:11434` works only when that service name exists on the application's
133network. A model server on the Docker host needs the appropriate host route rather
134than `localhost` inside the application container. Register both a language and
135an embedding model actually installed in the local server.
137Local inference avoids provider API charges, but still consumes local compute.
138Check all stages: content extraction, transcription, embeddings, chat, and speech
139can use separate remote providers. Confirm these settings before restricted data
140is ingested or a podcast is generated.

Ollama and local processing

Use upstream's Ollama Compose example for a matching network and volume definition. A provider URL such as http://ollama:11434 works only when that service name exists on the application's network. A model server on the Docker host needs the appropriate host route rather than localhost inside the application container. Register both a language and an embedding model actually installed in the local server.

Local inference avoids provider API charges, but still consumes local compute. Check all stages: content extraction, transcription, embeddings, chat, and speech can use separate remote providers. Confirm these settings before restricted data is ingested or a podcast is generated.

Raw lines 128 to 141
142## Running from source
144Docker is a convenient deployment, not a mandatory application runtime. Follow
145upstream's source installation and its lockfile for interpreter/dependency versions.
146Its documented setup uses `uv sync`, a SurrealDB service, a Next.js frontend, and
147separate API/worker processes. In the upstream checkout, after configuring `.env`:
149```bash
150make api
151```
153In a separate terminal:
155```bash
156make worker
157```
159A working `/health` endpoint does not prove the worker is running. Without it,
160background ingestion/embedding/podcast jobs remain pending. The source frontend's
161development port is 3000, unlike Docker's 8502. No separate Python client SDK is
162required by this skill; the bundled requests wrappers call the REST API directly.

Running from source

Docker is a convenient deployment, not a mandatory application runtime. Follow upstream's source installation and its lockfile for interpreter/dependency versions. Its documented setup uses uv sync, a SurrealDB service, a Next.js frontend, and separate API/worker processes. In the upstream checkout, after configuring .env:

make api

In a separate terminal:

make worker

A working /health endpoint does not prove the worker is running. Without it, background ingestion/embedding/podcast jobs remain pending. The source frontend's development port is 3000, unlike Docker's 8502. No separate Python client SDK is required by this skill; the bundled requests wrappers call the REST API directly.

Raw lines 142 to 163
164## Backup and restore
166Keep a consistent copy of **both** persistent directories and retain the encryption
167key separately. For a local deployment using the upstream bind mounts, a cold
168filesystem backup is an illustrative option: stop both services, archive the data,
169then restart. Use a fresh backup path; do not overwrite the only prior backup.
171```bash
172docker compose stop
173tar -czf open-notebook-backup-YYYYMMDD.tar.gz notebook_data surreal_data
174docker compose start
175```
177To restore, stop the services, preserve the current directories, restore the archive
178into the same Compose directory, and use the same encryption key and compatible
179image/database versions before starting. Test restoration on a separate deployment.
180A database-only export is insufficient for files and SQLite conversation state.

Backup and restore

Keep a consistent copy of both persistent directories and retain the encryption key separately. For a local deployment using the upstream bind mounts, a cold filesystem backup is an illustrative option: stop both services, archive the data, then restart. Use a fresh backup path; do not overwrite the only prior backup.

docker compose stop
tar -czf open-notebook-backup-YYYYMMDD.tar.gz notebook_data surreal_data
docker compose start

To restore, stop the services, preserve the current directories, restore the archive into the same Compose directory, and use the same encryption key and compatible image/database versions before starting. Test restoration on a separate deployment. A database-only export is insufficient for files and SQLite conversation state.

Raw lines 164 to 180