# Open Notebook puts Notebook LM in Docker with 18+ providers and basic citations

> Open Notebook is an MIT licensed, self hosted research assistant that replaces Google's Notebook LM with a Docker Compose stack, a choice of more than 18 model providers, and a REST API. It is strongest on control, deployment freedom, and podcast speakers, and it openly lists its citations as basic references rather than sources with page level support.

**lfnovo/open-notebook** — An Open Source implementation of Notebook LM with more flexibility and features

- Repository: https://github.com/lfnovo/open-notebook
- Website: https://www.open-notebook.ai
- Stars: 39,694 · Forks: 4,592
- Language: TypeScript
- License: MIT
- Published: 2026-08-17 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/lfnovo-open-notebook

## The quick start is one curl, one key edit, and port 8502

Docker Desktop is the only prerequisite the project names, and installation is a compose file rather than a package manager step. You fetch the file from the repository root:

```bash
curl -o docker-compose.yml https://raw.githubusercontent.com/lfnovo/open-notebook/main/docker-compose.yml
```

Step 2 tells you to edit a single line in that file before anything launches, and step 3 is the entire start sequence:

```bash
docker compose up -d
```

The next instruction is to wait 15 to 20 seconds and open http://localhost:8502. Behind that one address sit two published services, the web UI on 8502 and a REST API on 5055, both declared in the same compose file. Provider credentials are not needed to boot the stack. Model setup happens afterwards in the browser, which means a fresh install is reachable long before it is useful.

## The compose file ships a public encryption key placeholder

Before anything starts, the file contains a value that is published in the repository:

```yaml
- OPEN_NOTEBOOK_ENCRYPTION_KEY=change-me-to-a-secret-string
```

That key is what encrypts your API keys in the database, so the literal is a placeholder you are expected to replace with your own secret string, and the .env.example file suggests a minimum of 16 characters. Nothing in the start sequence checks whether you changed it. Skip the edit and the app still boots and still accepts provider credentials, but those values are encrypted under a key anyone can read from the repository. Changing the variable later does not rewrite what is already stored, so the placeholder is a decision you have to get right on the first run.

## SurrealDB starts as root:root on loopback with a RocksDB file

The database service is a pinned image whose start command embeds the credentials inline:

```yaml
    command: ["start", "--log", "info", "--user", "${SURREAL_USER:-root}", "--pass", "${SURREAL_PASSWORD:-root}", "rocksdb:/mydata/mydatabase.db"]
```

Both values fall back to root when the variables are absent, and the application service reads the same pair, so the two never drift apart. The app connects through `SURREAL_URL=ws://surrealdb:8000/rpc` with namespace and database both named open_notebook. Data lands in ./surreal_data on the host rather than in a named volume, which makes a backup a plain file copy. The host port is deliberately pinned to `127.0.0.1:8000:8000`, so a remote database GUI cannot reach it until you widen the binding yourself.

## Provider keys moved to the UI and the environment variables are marked deprecated

Model setup happens after the browser opens: go to Models, click + Add Configuration, paste the key, press Test, then Sync Models and pick which ones to include, and finally use Auto-Assign Defaults to map roles to models. Credentials entered this way are encrypted in the database, can be rotated without a container restart, and several keys per provider are allowed. The .env.example file marks the old per provider variables, including the commented OpenAI line, as a DEPRECATED fallback that still works today with no promise about future releases, and it points headless and CI setups at a discussion where a declarative provisioning contract is still being designed. Until that exists, an unattended deployment has no documented way to seed keys.

## Citations resolve to basic references, not to page level sources

The feature comparison is candid in exactly one row: Open Notebook's citations are listed as basic references that will improve, against sources backed citations in Google's Notebook LM. Every other row is claimed in the project's favor, including data sovereignty, provider choice, a full REST API, and a 1 to 4 speaker podcast range, so this is the single concession in the table. For a reader the cost is concrete. A generated answer can name a document without pointing at the page or passage that supports a claim, which means you still have to open the source and search it yourself before you can cite the output anywhere. No option in the start sequence changes that.

## Port 5055 is published without an auth layer in the compose file

The application service publishes two ports and nothing else:

```yaml
      - "8502:8502"  # Web UI
      - "5055:5055"  # REST API
```

There is no reverse proxy, no TLS terminator, and no authentication service in the file, and both bindings listen on all interfaces. The same file goes out of its way to loopback bind the database, so the contrast looks deliberate rather than accidental, yet the README does not document how the REST API is protected in a shared or hosted deployment. Run this on a machine with a routable address and the full automation surface the comparison table advertises is reachable without any credential step described in the docs, while the provider keys behind it rest on the encryption key from step 2.

## Podcasts take 1 to 4 custom speakers, and the example file is misspelled

Podcast generation is the clearest claimed advantage: the comparison table gives Open Notebook 1 to 4 speakers with custom profiles against a two speaker cap in Notebook LM, and the backend depends on the podcast-creator package to do it. The trade is that you assemble the surrounding pipeline yourself. The examples directory ships six compose variants, docker-compose-dev, docker-compose-full-local, docker-compose-ollama, docker-compose-single, docker-compose-speaches, and one under easypanel, and only the Ollama file is named in the start guide as the free local AI path. The speaker example is spelled speaches in the repository itself. Each file encodes a different deployment shape, so choosing the wrong one costs you a container rebuild instead of a warning.

## The backend accepts only Python 3.11 and 3.12

GitHub lists TypeScript as the primary language, which reflects the Next.js and React front end, but the server is Python and the version window is narrow. pyproject.toml declares `requires-python = ">=3.11,<3.13"` and the Dockerfile builds on `python:3.12-slim-trixie`, so 3.10 and 3.13 are both out of range. Dependencies are pinned hard at major version boundaries, including langchain under 2, langgraph under 2, esperanto under 3, and content-core under 3, so an upstream release that pushes any of those past its ceiling becomes a code change rather than a version bump. The Dockerfile also retries npm ci up to five times with 15 second waits, a concession to registry resets on the emulated arm64 leg of the multi-arch build.

## Conclusion

Open Notebook earns its place when you want Notebook LM shaped workflows on hardware you control and are willing to own the deployment, because the compose path is short, the provider layer is broad, and the 1 to 4 speaker podcast range is the one capability the comparison table clearly claims as a win. Skip it if citation traceability matters more to your work than self hosting, since the project itself lists citations as basic references. Before deploying anywhere reachable, confirm the encryption key has been replaced, decide whether the loopback database binding and the open 5055 port are acceptable, and check whether a declarative way to provision provider keys exists for your CI.

## FAQ

### How to install open notebook AI?

Docker Desktop is the only prerequisite. Download docker-compose.yml with curl, replace OPEN_NOTEBOOK_ENCRYPTION_KEY with your own secret string, run docker compose up -d, wait 15 to 20 seconds, and open http://localhost:8502, then add provider keys under Models.

### is open notebook free

The project is MIT licensed and self hosted, and its comparison table lists cost as paying only for AI usage. Groq is linked with a free tier, and examples/docker-compose-ollama.yml is the documented path for running models locally.

### Is an open notebook as good as a NotebookLM?

The project's own table claims advantages in privacy, provider choice, podcast speakers, API access, deployment, and customization, and concedes one row, citations, which it lists as basic references that will improve against sources backed citations.

### how to install open notebook on mac

No macOS specific steps are given. The documented path is Docker Desktop plus docker compose up -d, and the Dockerfile also has a single container target that bundles the application with SurrealDB instead of running them as separate services.

### anythingllm vs open notebook

The repository contains no comparison with AnythingLLM. The feature table in the README compares Open Notebook only against Google Notebook LM, across privacy, provider choice, podcast speakers, content transformations, API access, deployment, citations, customization, and cost.

## Sources

- [Official documentation](https://www.open-notebook.ai)
- [Official README](https://github.com/lfnovo/open-notebook#readme)
- [Project repository](https://github.com/lfnovo/open-notebook)
- [Release notes](https://github.com/lfnovo/open-notebook/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/lfnovo-open-notebook
