Skip to main content
The recommended way to self-host Nous. Tested on Ubuntu 24.04 with 2GB RAM and 2 vCPUs.
You will need a Supabase project before starting. The free tier is enough to get going.

What you get

Docker Compose brings up 5 containers:
  • api — Express API server, identity resolution, signal ingestion
  • worker — Background jobs: AI synthesis, two-way sync, ICP scoring
  • frontend — Nginx serving the React SPA
  • redis — Session state and job queue
  • caddy — Automatic SSL and subdomain routing

Step 1: Get the files

Clone the repo or download just the production files:

Step 2: Configure environment

Open nous.env and fill in:
Optional — integrations. These are instance-level: set the ones you want, then restart. Your agent will tell you which are missing during onboarding (it can’t set env vars for you).

Step 3: Run the database schema

Required before first boot. Skip this and the app will start but nothing will work.
Open your Supabase project → SQL Editor → paste and run the full contents of supabase/schema.sql. This one file is the complete schema — every table, view, function, trigger, RLS policy, and index, plus the pgcrypto and vector extensions it depends on. A fresh install needs only this file; do not also run the files in supabase/migrations/ (those are the incremental history and are only used when updating an existing install — see Updating below).

Step 4: Point your DNS

Create two A records pointing to your server IP: Caddy handles SSL automatically once DNS resolves.

Step 5: Start

First run builds all images — takes 2–3 minutes. After that:
  • Frontend → https://app.yourdomain.com
  • API → https://api.yourdomain.com

Step 6: Enable email auth in Supabase

Open your Supabase project → Authentication → Providers → Email and turn it on. Without this, no one can sign up. If you want Google sign-in, enable the Google provider in the same panel and set your OAuth client ID and secret.

Step 7: Create your first user

Open https://app.yourdomain.com and click Sign up. The first account becomes the owner. You’ll land on the Connect screen — Nous is operated by your agent, so this screen stays up until your agent has onboarded the workspace.

Step 8: Connect your agent

Nous is set up by your agent, not by clicking through the app. Point your agent at this instance. Claude Code
Codex — add to ~/.codex/config.toml:
Cursor / any MCP host — add to mcp.json:
Then sign in — this mints a key and saves it (with your API URL) to ~/.nous/config.json, which the MCP reads automatically:
The --url is what points your agent at your own instance instead of Nous Cloud — it’s the one self-host-specific bit. Prefer to paste a key instead of signing in? Create one at Settings → API Keys and set it directly in the MCP config:

Step 9: Onboard — let your agent set it up

Tell your agent:
Set me up — onboard my workspace and build my playbook.
Your agent reads get_workspace_status and walks you through setup in order: profile → connect channels (Gmail / LinkedIn / a meeting note-taker) → enrichment → webhooks → import your CRM contacts (CSV) → build the ICP scoring model. The Connect screen unlocks the moment the workspace is onboarded, and drops you on the live Ops log. Because it’s self-hosted, your agent knows that LinkedIn (Unipile), email (Resend), and Gmail (Google OAuth) are configured in nous.env (Step 2) — it’ll tell you which env vars to set and to restart. Enrichment (Prospeo / Apollo) is bring-your-own-key, and your agent connects it directly.
Self-hosters don’t have Lead Lists, CRM Sync, Triggers, or Reports — those are Nous Cloud only. Everything else (the context graph, the MCP server + all agent tools, the ICP scoring model, enrichment, integrations) is fully open.

Updating

The images are built locally from source, so pull the latest code and rebuild:
git pull fetches the new code, --build recompiles the images from it, and -d restarts only the containers that changed (Redis and Caddy are left untouched). The frontend is rebuilt too — Vite bakes the UI into a static bundle at build time, so a plain restart won’t pick up frontend changes.
Some updates ship new database migrations under supabase/migrations/. These are not applied automatically. After pulling, check that folder for files newer than your last update and run any new ones in your Supabase SQL Editor before (or right after) rebuilding. Skipping a migration will make the new code error against an outdated schema.

Logs

Stopping