How to Set Up a Local Development Environment with API and SurrealDB for Open Notebook

Docker Compose provides the fastest path to launch the Open Notebook FastAPI backend and SurrealDB together, exposing the web interface on port 8502 and the REST API on port 5055.

Open Notebook is a FastAPI-based application that persists all data in SurrealDB. Setting up a local development environment requires orchestrating both services so the API can communicate with the database over WebSocket. This guide walks you through the Docker Compose approach and the optional source-based workflow using the actual implementation from the lfnovo/open-notebook repository.

Configure Docker Compose for Local Development

The repository includes a pre-configured docker-compose.yml that defines both the SurrealDB and Open Notebook services. This configuration uses the official surrealdb/surrealdb:v2 image for the database and lfnovo/open_notebook:v1-latest for the application.

Create a docker-compose.yml file with the following content:

services:
  surrealdb:
    image: surrealdb/surrealdb:v2
    command: start --log info --user root --pass root rocksdb:/mydata/mydatabase.db
    user: root
    ports:
      - "8000:8000"
    volumes:
      - ./surreal_data:/mydata
    restart: always

  open_notebook:
    image: lfnovo/open_notebook:v1-latest
    ports:
      - "8502:8502"
      - "5055:5055"
    environment:
      - OPEN_NOTEBOOK_ENCRYPTION_KEY=change-me-to-a-secret-string
      - SURREAL_URL=ws://surrealdb:8000/rpc
      - SURREAL_USER=root
      - SURREAL_PASSWORD=root
      - SURREAL_NAMESPACE=open_notebook
      - SURREAL_DATABASE=open_notebook
    volumes:
      - ./notebook_data:/app/data
    depends_on:
      - surrealdb
    restart: always

Set the Encryption Key

Before starting the stack, you must replace the placeholder encryption key in the docker-compose.yml file. The OPEN_NOTEBOOK_ENCRYPTION_KEY environment variable is used by open_notebook/utils/encryption.py to encrypt stored credentials like API keys.

Generate a secure random string and update the environment variable:


# Generate a random hex string

openssl rand -hex 16

# Or update the file directly

sed -i 's/change-me-to-a-secret-string/your-generated-key-here/' docker-compose.yml

Launch the Development Stack

Start both services with Docker Compose. The depends_on directive ensures SurrealDB starts before the Open Notebook API.

docker compose up -d

Docker will pull the required images and create containers for both services. After approximately 15-20 seconds, the services will be ready:

Verify the API health endpoint:

curl http://localhost:5055/health

# Expected response: {"status":"ok"}

Verify the SurrealDB Connection

The Open Notebook API establishes the database connection during startup via open_notebook/database/async_migrate.py. This module creates an async SurrealDB client using the WebSocket URL and credentials defined in your environment variables.

To test the connection independently, use the SurrealDB Python client:

import asyncio
from surrealdb import Surreal

async def test_connection():
    db = Surreal("ws://localhost:8000/rpc")
    await db.connect()
    await db.signin({"user": "root", "pass": "root"})
    await db.use("open_notebook", "open_notebook")
    result = await db.query("INFO FOR DATABASE")
    print(result)

asyncio.run(test_connection())

Once connected, open the UI at localhost:8502, navigate to Models, and add a provider configuration (such as an OpenAI API key). Click Test to confirm the API can write encrypted credentials to SurrealDB via the endpoints defined in api/routers/models.py.

Run from Source for Development

If you need to modify the FastAPI source code rather than use the pre-built image, run the stack from source:

  1. Clone the repository and install dependencies:

    pip install -r requirements.txt
  2. Start SurrealDB locally (using the same Docker image):

    docker run -d --name surrealdb -p 8000:8000 \
      surrealdb/surrealdb:v2 start --user root --pass root rocksdb:/mydata/db
  3. Export the required environment variables:

    export OPEN_NOTEBOOK_ENCRYPTION_KEY="your-secret-key"
    export SURREAL_URL="ws://localhost:8000/rpc"
    export SURREAL_USER="root"
    export SURREAL_PASSWORD="root"
    export SURREAL_NAMESPACE="open_notebook"
    export SURREAL_DATABASE="open_notebook"
  4. Launch the FastAPI server:

    uv run python run_api.py

The entry point api/main.py mounts all routers including /sources, /notes, and /search, and registers CORS middleware for the frontend.

Key Source Files

Understanding these core files helps when debugging or extending the local environment:

Summary

  • Docker Compose is the recommended approach for setting up a local Open Notebook development environment with SurrealDB.
  • The docker-compose.yml configures SurrealDB on port 8000 and maps the Open Notebook UI (8502) and API (5055).
  • You must set a unique OPEN_NOTEBOOK_ENCRYPTION_KEY before starting the stack to ensure credential security.
  • The API connects to SurrealDB via WebSocket using parameters defined in environment variables, initialized in async_migrate.py.
  • For code modifications, run from source using run_api.py after starting SurrealDB separately.

Frequently Asked Questions

How do I change the default SurrealDB credentials in local development?

Edit the command line in the docker-compose.yml surrealdb service to specify different --user and --pass values, then update the corresponding SURREAL_USER and SURREAL_PASSWORD environment variables in the open_notebook service. Restart the stack with docker compose up -d to apply changes.

Why does the Open Notebook container fail to start with "Connection refused" errors?

This typically occurs when the Open Notebook API attempts to connect before SurrealDB is fully initialized. The depends_on directive in Docker Compose only controls startup order, not readiness. Wait 15-20 seconds after starting the stack, or configure a health check dependency in your compose file to ensure SurrealDB accepts connections before the API starts.

Can I use a different database backend instead of SurrealDB?

No. According to the source code in open_notebook/database/async_migrate.py, the application is specifically designed to use SurrealDB's WebSocket protocol and query syntax. The Surreal client is hardcoded into the database abstraction layer, making SurrealDB a requirement for running Open Notebook.

How do I persist data between container restarts?

The docker-compose.yml includes volume mappings that persist data to your host filesystem. SurrealDB stores data in ./surreal_data mapped to /mydata inside the container, while Open Notebook uses ./notebook_data mapped to /app/data. These directories survive Docker container restarts and recreations.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →