Google's NotebookLM is brilliant until you remember what you fed it: board packs, HR policies, client contracts. That corpus lives on someone else's infrastructure, under terms you didn't negotiate. For a lot of teams that's a non-starter — not because they're anti-AI, but because the documents were never allowed to leave the building in the first place.
SurfSense is the open-source answer that's been gathering steam (16k+ GitHub stars). It pitches itself as an air-gapped NotebookLM alternative: an AI agent that researches, transforms, and edits your files — PDFs, Word, Excel, slides, images, audio — with citations, on hardware you control. The desktop app is the headline; the Docker stack is how you run it for a team on a Canadian VPS.
What SurfSense actually does
Research with sources. Drop folders or files into a workspace and ask questions. Answers come back with citations, including scanned PDFs (OCR for Latin, Chinese, and Japanese script). This is the NotebookLM-shaped workflow — but the index stays on your disk unless you point the app at a remote API.
Edit and transform, not just chat. Unlike NotebookLM, SurfSense can produce changed files: fill PDF forms, stamp watermarks, merge and split pages, edit Word with tracked changes, tweak Excel formulas, replace PowerPoint text, run pandas on CSVs, even generate podcasts with on-machine voice by default. Edits always land as a new file; originals stay untouched.
Pick your models. Any OpenAI-compatible endpoint — Ollama on the LAN, vLLM, or cloud keys if policy allows. Image generation for infographics needs a separate image model; nothing is forced on you at install time.
Study extras. Mind maps, flashcards, and quizzes show up in the app for people using it like a research notebook, not just a chat pane.
Desktop vs Docker: two ways to self-host
Most contributors ship a desktop build first — Windows installer, macOS Apple Silicon DMG, Linux AppImage/deb. Index local, no account, fully offline if you use a local model. That's the privacy story in one sentence.
For a shared team instance, use the official compose stack under docker/ on the dev branch (docs: surfsense.com legacy Docker install). You get:
- Caddy on port 3929 by default (
LISTEN_HTTP_PORT) as the public entry - Frontend + backend (
ghcr.io/modsetter/surfsense-web/surfsense-backend) - Postgres + pgvector for embeddings and app data
- Redis + Celery workers for indexing and long jobs
- SearxNG for optional web research inside the agent
- OpenSandbox — spawns sibling containers via the host Docker socket for code execution (plan security accordingly)
- Rocicorp Zero cache layer for sync — first boot can take several minutes; healthchecks allow a long start period
Copy docker/.env.example to .env, generate SECRET_KEY (openssl rand -base64 32), set DEPLOYMENT_MODE=self-hosted, and leave SUNSET_MODE empty. That sunset flag is only for the hosted product winding down — self-hosters should not set it.
Heads-up: SurfSense's cloud app is sunsetting; if you used the hosted web version, export workspaces before 18 October 2026 and import into desktop or your own Docker deployment.
SurfSense vs Khoj (and when to pick which)
We wrote up Khoj earlier — automations, Obsidian hooks, WhatsApp, scheduled digests. Khoj is a knowledge automation layer with a strong RAG story.
SurfSense is closer to document production: cited research plus file edits, PDF tooling, and Office workflows. If your pain is "NotebookLM but I can't upload the PDF," SurfSense fits. If your pain is "run a weekly research newsletter from my vault," Khoj still wins. Some shops will run both; most should pick one primary doc brain to avoid duplicate indexing.
Why put the Docker stack on your own server?
Team access without SaaS. Legal, finance, and ops can share one instance behind your SSO or VPN instead of emailing exports around.
Data residency. Postgres, object store volumes, and embeddings on a Canadian VPS give you a straight answer when counsel asks where research happened.
Air-gapped option. Desktop stays fully local; server deploy can use local inference only — no outbound model calls — if you firewall egress from the backend.
What running it takes
This is not a single-container hobby project. Budget 16 GB RAM minimum for the full compose stack on a small team; 32 GB if you're indexing large libraries or enabling GPU variants (SURFSENSE_VARIANT=cuda with NVIDIA Container Toolkit). Disk: fast SSD, plan for document object store growth — MAX_FILE_SIZE_MB defaults to 500 MB per file.
Back up Postgres and the object_store volume. Treat /var/run/docker.sock on OpenSandbox as privileged — isolate the host or use a dedicated VM. Put TLS in front (Caddy handles Let's Encrypt when SURFSENSE_SITE_ADDRESS and CERT_EMAIL are set) or terminate at your own reverse proxy.
ETL defaults to DOCLING for parsing; you can point embeddings at local sentence-transformers or an API. Read the env file comments before flipping every integration — WhatsApp bridge and Daytona sandbox hooks are there if you need them, not required day one.
Who it's for (and who should wait)
Good fit: research-heavy teams with sensitive PDFs, consultants who live in Word/Excel deliverables, anyone who wanted NotebookLM without uploading to Google, orgs standardizing on one self-hosted doc agent.
Maybe wait: if you only need chat with Ollama, Open WebUI is lighter. If you won't babysit Postgres, Redis, Celery, Zero, and sandbox plumbing, start with the desktop app on managed laptops before you commit a server.
Hosting it in Canada
We run heavy Docker stacks on Canadian infrastructure — TLS, backups that include pgvector DB and object storage, and firewall rules that keep sandbox spawn permissions on a dedicated box. SurfSense is exactly the kind of workload that punishes an undersized VPS during the first bulk import.
Tell us team size, document volume, and whether models stay local — we'll size RAM and disk so the agent stays useful after the demo folder is gone.