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:
- SurrealDB: Running on
ws://localhost:8000/rpc - Open Notebook UI: Available at http://localhost:8502
- REST API: Accessible at http://localhost:5055 with OpenAPI documentation at
/docs
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:
-
Clone the repository and install dependencies:
pip install -r requirements.txt -
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 -
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" -
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:
docker-compose.yml: Defines the multi-container setup with SurrealDB and Open Notebook servicesapi/main.py: FastAPI entry point that initializes the application and registers all API routersopen_notebook/database/async_migrate.py: Creates the async SurrealDB client on startup and runs database migrationsopen_notebook/utils/encryption.py: Handles credential encryption using theOPEN_NOTEBOOK_ENCRYPTION_KEYenvironment variableapi/routers/models.py: REST endpoints for managing AI provider configurationsrun_api.py: Convenience script to launch the API directly for local development
Summary
- Docker Compose is the recommended approach for setting up a local Open Notebook development environment with SurrealDB.
- The
docker-compose.ymlconfigures SurrealDB on port 8000 and maps the Open Notebook UI (8502) and API (5055). - You must set a unique
OPEN_NOTEBOOK_ENCRYPTION_KEYbefore 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.pyafter 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →