mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-08 22:22:17 +02:00
181 lines
7.3 KiB
Text
181 lines
7.3 KiB
Text
---
|
|
title: Docker Installation
|
|
description: Run SurfSense with Docker in minutes
|
|
---
|
|
|
|
Docker is the recommended way to run SurfSense. Everything — database, backend, frontend, background workers, real-time sync, and a reverse proxy — comes pre-configured.
|
|
|
|
**Prerequisites:** [Docker Desktop](https://www.docker.com/products/docker-desktop/) (or Docker Engine with Compose) must be installed and running.
|
|
|
|
## Option 1: One-Line Install Script (Recommended)
|
|
|
|
**Linux/macOS:**
|
|
|
|
```bash
|
|
curl -fsSL https://raw.githubusercontent.com/MODSetter/SurfSense/main/docker/scripts/install.sh | bash
|
|
```
|
|
|
|
**Windows (PowerShell):**
|
|
|
|
```powershell
|
|
irm https://raw.githubusercontent.com/MODSetter/SurfSense/main/docker/scripts/install.ps1 | iex
|
|
```
|
|
|
|
The script creates a `./surfsense/` directory with the compose files and a `.env`, generates a secret key, starts all services, and waits until they're healthy. It also:
|
|
|
|
- Detects NVIDIA GPUs and asks whether to use GPU acceleration, picking the compatible backend image automatically.
|
|
- Asks whether to enable automatic daily updates via [Watchtower](https://github.com/nicholas-fedor/watchtower) (updates can download several GB in the background — pass `--no-watchtower` to skip).
|
|
- Detects a legacy all-in-one installation and migrates its data automatically (see [Updating](/docs/docker-installation/updating#migrating-from-the-all-in-one-container)).
|
|
|
|
## Option 2: Manual Docker Compose
|
|
|
|
```bash
|
|
git clone https://github.com/MODSetter/SurfSense.git
|
|
cd SurfSense/docker
|
|
cp .env.example .env
|
|
# Edit .env — at minimum set SECRET_KEY (generate with: openssl rand -base64 32)
|
|
docker compose up -d
|
|
```
|
|
|
|
## Access SurfSense
|
|
|
|
After starting, everything is served through the bundled Caddy reverse proxy on a single origin:
|
|
|
|
- **SurfSense**: [http://localhost:3929](http://localhost:3929)
|
|
- **Backend API**: [http://localhost:3929/api/v1](http://localhost:3929/api/v1)
|
|
- **Zero sync**: `ws://localhost:3929/zero`
|
|
|
|
Sign up with email/password (local auth is the default) and you're in.
|
|
|
|
## Configuration
|
|
|
|
All configuration lives in a single `.env` file — `surfsense/.env` if you used the install script, `docker/.env` if you cloned manually. The bundled `.env.example` documents every option inline with comments and working defaults; edit the values you need and restart:
|
|
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
The defaults give you local email/password auth, local document parsing with Docling (no API keys), and local TTS/STT. Common things you might change, all documented in the file:
|
|
|
|
- **Authentication** — switch to Google OAuth login.
|
|
- **Document parsing** — switch to Unstructured or LlamaCloud (both need API keys).
|
|
- **Connector credentials** — OAuth apps for [external connectors](/docs/connectors/external) that need them on self-hosted deployments.
|
|
- **Messaging channels** — Telegram, WhatsApp, Slack, and Discord bots (see [Messaging Channels](/docs/messaging-channels)).
|
|
|
|
### NVIDIA GPU Acceleration
|
|
|
|
Add these values to `.env` to use the CUDA backend image (the host needs the NVIDIA Container Toolkit):
|
|
|
|
```dotenv
|
|
SURFSENSE_VARIANT=cuda
|
|
COMPOSE_FILE=docker-compose.yml:docker-compose.gpu.yml
|
|
SURFSENSE_GPU_COUNT=1
|
|
```
|
|
|
|
Use `SURFSENSE_VARIANT=cuda126` for older NVIDIA driver stacks. On Windows, use `;` instead of `:` in `COMPOSE_FILE`. Then apply:
|
|
|
|
```bash
|
|
docker compose pull && docker compose up -d --wait
|
|
```
|
|
|
|
### Custom Domain / Automatic HTTPS
|
|
|
|
Point DNS at your Docker host and set in `.env`:
|
|
|
|
```dotenv
|
|
SURFSENSE_SITE_ADDRESS=surf.example.com
|
|
LISTEN_HTTP_PORT=80
|
|
LISTEN_HTTPS_PORT=443
|
|
CERT_EMAIL=you@example.com
|
|
SURFSENSE_PUBLIC_URL=https://surf.example.com
|
|
```
|
|
|
|
Then `docker compose up -d --wait`. Caddy issues and renews Let's Encrypt certificates automatically — ports 80 and 443 must be reachable from the internet.
|
|
|
|
### Bring Your Own Proxy
|
|
|
|
If you already run nginx, Traefik, Cloudflare Tunnel, or another ingress, comment out the `proxy` service and route traffic to the internal services with the same path contract:
|
|
|
|
| Public path | Upstream |
|
|
|-------------|----------|
|
|
| `/auth/*` | `backend:8000` |
|
|
| `/api/v1/*` | `backend:8000` |
|
|
| `/zero/*` | `zero-cache:4848` |
|
|
| `/*` | `frontend:3000` |
|
|
|
|
Your proxy must preserve WebSocket upgrades for `/zero`, avoid buffering streaming responses, allow long-running requests, and support large uploads.
|
|
|
|
## What's Running
|
|
|
|
| Service | Description |
|
|
|---------|-------------|
|
|
| `proxy` | Caddy reverse proxy — the only public ingress |
|
|
| `db` | PostgreSQL with pgvector |
|
|
| `migrations` | Short-lived: runs database migrations, then exits |
|
|
| `redis` | Message broker for background tasks |
|
|
| `backend` | FastAPI application server |
|
|
| `celery_worker` | Background task processing (document indexing, etc.) |
|
|
| `celery_beat` | Periodic task scheduler |
|
|
| `zero-cache` | Real-time sync (replicates Postgres to browsers) |
|
|
| `frontend` | Next.js web application |
|
|
|
|
Migrations run first on every startup; everything else waits for them to succeed, so `docker compose up -d` after an update is always safe. Monitor startup with `docker compose ps` — services go from `(health: starting)` to `(healthy)`.
|
|
|
|
## Useful Commands
|
|
|
|
```bash
|
|
# View logs (all services, or one)
|
|
docker compose logs -f
|
|
docker compose logs -f backend
|
|
|
|
# Restart a service
|
|
docker compose restart backend
|
|
|
|
# Stop all services
|
|
docker compose down
|
|
|
|
# Stop and remove containers + volumes (destroys your data!)
|
|
docker compose down -v
|
|
```
|
|
|
|
To update SurfSense, see [Updating](/docs/docker-installation/updating).
|
|
|
|
## Building from Source (Contributors)
|
|
|
|
If you're contributing to SurfSense and want to build the images from your local checkout, use the dev compose file:
|
|
|
|
```bash
|
|
cd SurfSense/docker
|
|
docker compose -f docker-compose.dev.yml up --build
|
|
```
|
|
|
|
It builds the backend and frontend from source, publishes raw service ports for debugging, and includes pgAdmin at [http://localhost:5050](http://localhost:5050). There's also a `docker-compose.deps-only.yml` that runs just the dependencies (Postgres, Redis, zero-cache) in Docker while you run the backend and frontend natively — see [Manual Installation](/docs/manual-installation#alternative-let-docker-manage-all-dependencies).
|
|
|
|
## Troubleshooting
|
|
|
|
- **Port already in use**: Change `LISTEN_HTTP_PORT` in `.env` and restart. In domain mode, ports 80/443 are required for certificate issuance.
|
|
- **Permission errors on Linux**: Prefix `docker` commands with `sudo`, or add your user to the `docker` group.
|
|
- **Real-time updates not working**: Open DevTools → Console and check for WebSocket errors. The expected URL is `${SURFSENSE_PUBLIC_URL}/zero`.
|
|
- **Line ending issues on Windows**: Run `git config --global core.autocrlf true` before cloning.
|
|
|
|
### Migration service exited non-zero
|
|
|
|
The stack halts if migrations fail. Inspect what happened:
|
|
|
|
```bash
|
|
docker compose logs migrations
|
|
```
|
|
|
|
Slow disks (Windows / WSL2) may hit the default 900-second migration timeout — set `MIGRATION_TIMEOUT` in `.env` to increase it.
|
|
|
|
### Zero-cache stuck on `Unknown or invalid publications`
|
|
|
|
This means zero-cache started before migrations created its publication — usually only possible if you started services individually. Recover with:
|
|
|
|
```bash
|
|
docker compose down
|
|
docker volume rm surfsense-zero-cache # wipe the half-built replica
|
|
docker compose up -d # migrations run first, then zero-cache
|
|
```
|
|
|
|
The same recovery fixes `_zero.tableMetadata` crashes (a half-initialized replica left behind by a previous crash).
|