Self-Hosting RushDB
RushDB ships as a single Docker image that includes the API server and the dashboard. You bring Neo4j and a Postgres instance (for project/token management), configure a handful of environment variables, and you have a fully functional RushDB instance with no usage limits and no billing.
Prerequisites
- Docker and Docker Compose installed
- A running or accessible Neo4j 5+ instance (or let Docker Compose start one for you)
- A running PostgreSQL 14+ instance (or let Docker Compose start one)
- Optional: an OpenAI-compatible embedding API if you want semantic search
Option A: Full stack with Docker Compose (recommended)
This Compose file starts RushDB, Neo4j, and Postgres together. Copy it to an empty directory and run docker compose up -d.
# docker-compose.yml
version: '3.9'
services:
neo4j:
image: neo4j:5
environment:
NEO4J_AUTH: neo4j/rushdb-password
NEO4JLABS_PLUGINS: '["apoc"]'
ports:
- "7474:7474" # Neo4j browser (optional)
- "7687:7687" # Bolt protocol
volumes:
- neo4j_data:/data
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:7474 || exit 1"]
interval: 10s
retries: 10
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: rushdb
POSTGRES_USER: rushdb
POSTGRES_PASSWORD: rushdb-pg-password
volumes:
- pg_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U rushdb"]
interval: 5s
retries: 10
rushdb:
image: rushdb/rushdb:latest
depends_on:
neo4j:
condition: service_healthy
postgres:
condition: service_healthy
ports:
- "3000:3000"
environment:
RUSHDB_SELF_HOSTED: "true"
RUSHDB_LOGIN: admin
RUSHDB_PASSWORD: change-me-in-production
# Encryption key — must be exactly 32 characters
RUSHDB_AES_256_ENCRYPTION_KEY: "32-char-key-change-in-production"
# Neo4j
NEO4J_URL: bolt://neo4j:7687
NEO4J_USERNAME: neo4j
NEO4J_PASSWORD: rushdb-password
# Postgres
SQL_DB_TYPE: postgres
SQL_DB_URL: postgresql://rushdb:rushdb-pg-password@postgres:5432/rushdb
# Embedding (optional — remove these 4 lines to disable vector indexes)
RUSHDB_EMBEDDING_BASE_URL: https://api.openai.com/v1
RUSHDB_EMBEDDING_API_KEY: sk-...
RUSHDB_EMBEDDING_MODEL: text-embedding-3-small
RUSHDB_EMBEDDING_DIMENSIONS: "1536"
volumes:
neo4j_data:
pg_data:
docker compose up -d
RushDB will be available at http://localhost:3000.
Option B: RushDB against an existing Neo4j instance
If you already have Neo4j running (or an Aura instance), skip the neo4j service and point NEO4J_URL directly at it.
rushdb:
image: rushdb/rushdb:latest
ports:
- "3000:3000"
environment:
RUSHDB_SELF_HOSTED: "true"
RUSHDB_LOGIN: admin
RUSHDB_PASSWORD: change-me-in-production
RUSHDB_AES_256_ENCRYPTION_KEY: "32-char-key-change-in-production"
# Point at your existing Neo4j / Aura instance
NEO4J_URL: bolt+s://xxxxxxxx.databases.neo4j.io:7687
NEO4J_USERNAME: neo4j
NEO4J_PASSWORD: your-aura-password
SQL_DB_TYPE: postgres
SQL_DB_URL: postgresql://rushdb:rushdb-pg-password@postgres:5432/rushdb
See Connecting an Aura Instance for the full BYOC walkthrough.
Environment variable reference
Required
| Variable | Default in image | Description |
|---|---|---|
RUSHDB_SELF_HOSTED | true | Must be "true" to enable self-hosted mode and create the default admin account |
RUSHDB_LOGIN | admin | Dashboard login username |
RUSHDB_PASSWORD | password | Dashboard login password — change this |
RUSHDB_AES_256_ENCRYPTION_KEY | 32SymbolStringForTokenEncryption | Exactly 32-character key used to encrypt API tokens at rest — change this |
NEO4J_URL | — | Bolt URL of your Neo4j instance |
NEO4J_USERNAME | neo4j | Neo4j username |
NEO4J_PASSWORD | password | Neo4j password |
SQL_DB_URL | — | PostgreSQL connection string |
SQL_DB_TYPE | postgres | Database driver — only postgres supported |
Optional
| Variable | Default | Description |
|---|---|---|
RUSHDB_PORT | 3000 | Port the API server listens on |
RUSHDB_SERVE_STATIC | true | Serve the built dashboard from the same process |
RUSHDB_EMBEDDING_BASE_URL | https://api.openai.com/v1 | Base URL of any OpenAI-compatible embeddings endpoint |
RUSHDB_EMBEDDING_API_KEY | — | Bearer token for the embedding provider |
RUSHDB_EMBEDDING_MODEL | — | Model identifier (e.g. text-embedding-3-small). Omit to disable vector indexes entirely |
RUSHDB_EMBEDDING_DIMENSIONS | — | Must match the model's actual output dimensions |
RUSHDB_EMBEDDING_BATCH_SIZE | 500 | Records per embedding backfill batch |
RUSHDB_EMBEDDING_MAX_RUNTIME_MS | 50000 | Max ms the backfill scheduler spends per index per tick |
RUSHDB_PAGINATION_DEFAULT_LIMIT | 100 | Default page size when limit is not specified in a search query |
RUSHDB_PAGINATION_MAX_LIMIT | 1000 | Maximum allowed limit value — requests above this are clamped |
RATE_LIMITER_REQUESTS_LIMIT | 100 | Max requests per time window |
RATE_LIMITER_TTL | 1000 | Rate limiter window in milliseconds |
First boot
- Open
http://localhost:3000— you will see the RushDB dashboard login screen. - Sign in with the
RUSHDB_LOGIN/RUSHDB_PASSWORDyou configured. - Create your first project: click New Project, give it a name, and save.
- Copy the generated API key from the API Keys tab.
- Test the connection:
- Python
- TypeScript
- shell
from rushdb import RushDB
db = RushDB("YOUR_API_KEY", base_url="http://localhost:3000/api/v1")
result = db.records.find({"labels": ["TEST"]})
print(result) # → { data: [], total: 0 }
import RushDB from '@rushdb/javascript-sdk'
const db = new RushDB('YOUR_API_KEY', {
url: 'http://localhost:3000/api/v1'
})
const result = await db.records.find({ labels: ['TEST'] })
console.log(result) // → { data: [], total: 0 }
curl https://localhost:3000/api/v1/records/search \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"labels":["TEST"]}'
# → {"data":[],"total":0}
Connecting your SDK to a self-hosted instance
- Python
- TypeScript
- shell
from rushdb import RushDB
db = RushDB('YOUR_API_KEY', base_url='http://localhost:3000/api/v1')
import RushDB from '@rushdb/javascript-sdk'
const db = new RushDB('YOUR_API_KEY', {
url: 'http://localhost:3000/api/v1'
})
export RUSHDB_API_KEY="YOUR_API_KEY"
export RUSHDB_BASE="http://localhost:3000/api/v1"
curl "$RUSHDB_BASE/records/search" \
-H "Authorization: Bearer $RUSHDB_API_KEY" \
-H "Content-Type: application/json" \
-d '{"labels":["TEST"]}'
SQLite for single-node deployments
If you don't want to run a Postgres container, RushDB supports SQLite for the SQL layer (users, projects, tokens). Set SQL_DB_TYPE=sqlite and omit SQL_DB_URL:
rushdb:
image: rushdb/rushdb:latest
environment:
SQL_DB_TYPE: sqlite
SQL_DB_PATH: /data/rushdb.db # optional — defaults to ./rushdb.db
# ...other vars
volumes:
- rushdb_data:/data
SQLite is fine for a single RushDB container. Use Postgres for multi-replica deployments or anywhere you need concurrent writes from more than one process.
CLI commands
RushDB exposes CLI commands for user management inside the container — useful for scripted provisioning or password rotation:
# Create a new user
docker exec rushdb rushdb create-user admin@example.com securepassword123
# Update an existing user's password
docker exec rushdb rushdb update-password admin@example.com newsecurepassword456
Production hardening checklist
| Item | Action |
|---|---|
RUSHDB_PASSWORD | Set a strong password — never leave password |
RUSHDB_AES_256_ENCRYPTION_KEY | Generate a random 32-character string |
| Neo4j password | Change from the Compose default |
| TLS | Terminate TLS at a reverse proxy (nginx, Caddy, Traefik) in front of port 3000 |
| Postgres | Back up the rushdb Postgres database — it stores projects, tokens, and billing records |
| Neo4j | Enable Neo4j backups for your graph data |
| Embedding key | Rotate the embedding provider API key independently of the RushDB key |
Next steps
- Project Setup After Deployment — create projects, invite team members, configure per-project embedding models
- Connecting an Aura Instance — use an existing Neo4j Aura database as the RushDB data store
- BYOC vs Managed vs Self-hosted — choose the right deployment topology for your use case