Skip to main content
The compose file at infra/onprem/docker-compose.yml is the same one the desktop app runs. Point at it directly when you want Nora on a server or VM without the desktop shell.

Prerequisites

  • Docker Engine 20.10+ (docker --version).
  • The Docker Compose plugin (docker compose version).
  • Around 15 GB of free disk for the container images and Postgres volume.
  • 4 GB of RAM available to Docker (8 GB is more comfortable).

Quick start

1

Copy the env template

2

Set POSTGRES_PASSWORD

Compose refuses to boot without a real password. Open .env.onprem and replace CHANGE_ME_postgres_password with something you’d treat as a real credential — anything with the compose file can read it.
3

Bring the stack up

Nora is now serving at http://localhost:8090. First boot runs SQL migrations automatically.

What’s in the stack

Five services on an internal Docker network. Only nora-server publishes a host port.

How images resolve

Both nora-server and nora-llm-bridge follow the same resolution order:
  1. If the image is already present locally (loaded from a tarball, or built by a previous up), compose uses it.
  2. If the image isn’t local but the registry is reachable, compose pulls it from GHCR.
  3. If neither works, compose builds from source using the fallback build: block. First-time source builds take about 2 minutes for the bridge and 15 – 30 minutes for the server.
Set NORA_IMAGE_REGISTRY to point at a private registry — useful when air-gapped operators load the tarball into their own mirror.

Essential environment variables

Only one variable is required. Everything else has a sensible default.
  • POSTGRES_PASSWORD — the bundled Postgres container’s superuser password. Compose refuses to boot without a real value.
The most common overrides: OAuth and SSO credentials pass through unchanged: GOOGLE_OAUTH_CLIENT_ID / GOOGLE_OAUTH_CLIENT_SECRET, GITHUB_OAUTH_CLIENT_ID / GITHUB_OAUTH_CLIENT_SECRET, and provider API keys like ANTHROPIC_API_KEY.

The laptop wrapper

For people who’d rather not memorise compose flags, infra/onprem/nora-laptop.sh is a friendlier surface for the same stack.
start generates a random POSTGRES_PASSWORD for you on first run and writes it into .env.onprem. You can boot without touching the file first. Edit .env.onprem later to attach a license key or wire OAuth.

Where your data lives

  • The pgdata volume holds Postgres data — workspaces, flows, memory, traces, everything transactional.
  • The qdrantdata volume holds the Qdrant vector index, and is only used when NORA_VECTOR_STORE=qdrant.
  • .env.onprem holds your configuration.
Back up all three together for a full restore. docker volume inspect nora-onprem_pgdata shows where the driver mounts them.

Upgrade

1

Point at a newer tag

The release pipeline publishes tags to GHCR.
2

Pull and restart

Migrations run automatically on the new server’s first boot.
Migrations are additive-only. An older server won’t start against a newer schema, so plan any downgrade against a matching database snapshot.

Uninstall

Container images stay in the Docker image store. Remove them with docker image prune if you want the disk back.

Air-gap tarball

The same compose file with the images bundled in one archive.

Kubernetes (Helm)

The same five services on a cluster with ingress and TLS.

Desktop app

This compose file wrapped in a native window.