Manual Installation
Set up SurfSense from source, component by component
This guide sets up SurfSense without Docker. Choose this path if you want to contribute to SurfSense or need full control over each component. If you just want to run SurfSense, the Docker installation is much faster.
What You'll Need
- Python 3.12+ — backend runtime
- Node.js 20+ and pnpm — frontend runtime
- PostgreSQL 14+ with the pgvector extension — database
- Redis — message broker for background tasks
- Git — to clone the repository
- uv — Python package manager (install instructions)
Clone the repository first:
git clone https://github.com/MODSetter/SurfSense.git
cd SurfSenseDecisions to Make Up Front
Authentication. SurfSense supports local email/password auth (the default, no setup needed) or Google OAuth login. For Google login you need an OAuth client from the Google Cloud Console — the Google connectors guide walks through creating one.
Document parsing (ETL). SurfSense converts uploaded files with one of three services:
- Docling (default) — runs locally, no API key, privacy-friendly. Supports PDF, Office docs, images, HTML, CSV.
- Unstructured — needs an API key from Unstructured Platform. Supports 34+ formats.
- LlamaCloud — needs an API key from LlamaCloud. Supports 50+ formats.
You only need one. Docling is the easiest way to start.
Backend Setup
1. Configure the Environment
Copy the example environment file:
Linux/macOS:
cd surfsense_backend
cp .env.example .envWindows (PowerShell):
cd surfsense_backend
Copy-Item -Path .env.example -Destination .env.env.example is the source of truth for configuration — every variable is documented inline with comments and sensible defaults. At minimum, set your PostgreSQL connection string and a JWT secret key (generate one with openssl rand -base64 32). Everything else — auth type, ETL service, embeddings, TTS/STT, connector credentials — is optional and explained in the file itself.
For separate embedding servers, set EMBEDDING_BASE_URL with Chonkie/LiteLLM embedding models; OLLAMA_EMBEDDING_BASE_URL is also supported as an Ollama-specific fallback.
2. Install Dependencies
# From surfsense_backend/
uv sync3. Run Database Migrations
# From surfsense_backend/
uv run alembic upgrade head4. Start Redis
Linux:
sudo systemctl start redis
# or run directly
redis-servermacOS (Homebrew):
brew services start redisWindows — run Redis in Docker (easiest):
docker run -d --name redis -p 6379:6379 redis:latestVerify it's running:
redis-cli ping
# Should return: PONG5. Start the Celery Worker
In a new terminal, start the worker that handles background tasks (document indexing, connector syncs):
Linux/macOS:
cd surfsense_backend
DEFAULT_Q="${CELERY_TASK_DEFAULT_QUEUE:-surfsense}"
uv run celery -A celery_worker.celery_app worker --loglevel=info --concurrency=1 --pool=solo --queues="${DEFAULT_Q},${DEFAULT_Q}.connectors,${DEFAULT_Q}.gateway"Windows (PowerShell):
cd surfsense_backend
uv run celery -A celery_worker.celery_app worker --loglevel=info --concurrency=1 --pool=solo --queues="surfsense,surfsense.connectors,surfsense.gateway"Optionally, run Flower in another terminal to monitor tasks at http://localhost:5555:
uv run celery -A celery_worker.celery_app flower --port=55556. Start Celery Beat (Scheduler)
In another terminal, start the scheduler that triggers periodic tasks (like scheduled connector syncs). Without it, scheduled tasks won't run.
cd surfsense_backend
uv run celery -A celery_worker.celery_app beat --loglevel=info7. Run the Backend
# From surfsense_backend/
uv run main.py
# Or with hot reloading for development
uv run main.py --reloadYou should see the server running on http://localhost:8000.
Frontend Setup
1. Configure the Environment
Linux/macOS:
cd surfsense_web
cp .env.example .envWindows (PowerShell):
cd surfsense_web
Copy-Item -Path .env.example -Destination .envAs with the backend, .env.example documents every option inline. Make sure the auth type and ETL service match what you configured for the backend, and that the backend URL points at http://localhost:8000.
2. Install Dependencies and Run
# Install pnpm if you don't have it
npm install -g pnpm
pnpm install
pnpm run devThe frontend should now be running at http://localhost:3000.
Browser Extension (Optional)
The SurfSense browser extension saves any webpage — including those behind authentication — straight into your knowledge base.
cd surfsense_browser_extension
cp .env.example .env # set the backend URL, documented inline
pnpm install
pnpm build # Chrome (default)
pnpm build --target=firefox # or Firefox
pnpm build --target=edge # or EdgeLoad the built extension in your browser's developer mode and configure it with your SurfSense API key. See the Plasmo build docs for details.
Verify Your Installation
- Open http://localhost:3000 and sign in.
- Create a workspace and upload a document.
- Watch the upload status update live without refreshing — this confirms the SSE connection is active.
- Chat with your uploaded content.
Troubleshooting
- Database connection issues: Verify PostgreSQL is running and pgvector is installed.
- Redis connection issues:
redis-cli pingshould returnPONG. Check the Redis URL in your backend.env. - Celery worker issues: Make sure the worker is running in a separate terminal and check its logs.
- File upload failures: Validate your ETL service API key, or use Docling which needs none.
- Real-time updates not working: Open DevTools → Network → Filter by "eventsource" and verify the
/api/v1/sse/eventsconnection is open. Check backend logs for Redis errors. EnsureREDIS_URLin your.envis correct and Redis is running (redis-cli pingreturns PONG).
Next Steps
- Set up connectors to bring in your tools and services.
- Connect local models like Ollama or LM Studio.
- For production, put a reverse proxy in front, add SSL, and set up database backups.