Skip to main content
Nowledge MemNowledge Mem

Linux Server Deployment

Run Nowledge Mem as a headless server on Linux without a desktop environment

Nowledge Mem can run as a headless server on Linux machines without a GUI. For a real server setup, use a Linux package and manage it from the command line. You can then open the built-in web app from a browser on the same machine, or connect other clients with an API key.

Availability

Background intelligence features such as daily briefings, insight detection, and knowledge graph enrichment require a configured Remote LLM and the appropriate license for your build. The server guide itself is about deployment, not packaging.

Use sudo for package installation and system service installation. Run day-to-day commands like nmem serve, nmem config ..., nmem license ..., and nmem tui as your normal Linux user. Recent builds block these stateful commands when you reach root through sudo or another elevation step, so a fresh install does not silently create root-owned Mem state in the wrong user environment. If you intentionally log in as root on a root-only VPS, Mem will still use /root normally.

System Requirements

RequirementSpecification
Operating SystemUbuntu 22.04+, Debian 12+, or compatible (via AppImage)
Architecturex86_64 for .deb / AppImage; x86_64 and arm64 for Docker
Memory (RAM)8 GiB minimum (16 GiB recommended)
Disk Space10 GiB available
Dependencieslibgtk-3-0, libwebkit2gtk-4.1-0, zstd (installed automatically by .deb)

Installation

Set up the APT repository for automatic updates via apt upgrade:

curl -fsSL https://nowledge-co.github.io/community/apt/install.sh | sudo bash
sudo apt-get install nowledge-mem

This adds the GPG signing key and repository source. To update only Mem later, run sudo apt-get update && sudo apt-get install --only-upgrade nowledge-mem. Normal system-wide upgrades still work through sudo apt-get update && sudo apt-get upgrade, or via unattended-upgrades if configured.

For a headless-first Linux server, prefer the APT, Docker, or .deb install path. AppImage is best for portable/manual use, not unattended server setup. It does not install the nmem CLI into your PATH, so it is not the cleanest nmem + systemd workflow on a machine with no desktop session.

If you download packages from a terminal, use the commands above as written. They include a browser User-Agent because some download endpoints return 403 to plain curl / wget requests.

APT and .deb installs automatically:

  • Installs the bundled Rust server and CLI binaries
  • Creates the nmem CLI at /usr/local/bin/nmem
  • Configures the APT repository for automatic updates (if installed via APT)
  • Sets up the desktop entry (ignored on headless servers)

Verify the CLI is available:

nmem --version

If you used the AppImage instead, run the AppImage file directly each time. It does not add nmem to your PATH.

Docker (preview)

This page covers the .deb / APT / systemd path on Linux servers. Docker is a separate deployment model with its own walkthrough. It uses the same Mem backend, same web app, and same data, but the lifecycle (compose, bind mounts, image upgrades, optional web-UI auto-update) is different enough to live on its own page.

See Docker Deployment for the full guide: when Docker is the right choice (VPS, NAS, cloud VM, homelab), supported architectures (amd64 + arm64), quick start with nmemctl, the "For your agent" skill, where your data lives, memory tuning, image verification, Caddy TLS, backups and migration, and the optional web-UI auto-update.

Quick Start

For a real Linux server, set up the background service first. That gives you one stable local Mem server so the next commands work cleanly from SSH, across new terminals, and after reboot.

Install the background service

Recommended on servers:

sudo nmem service install --service-user <linux-user>

If you truly want a user-level service instead:

nmem service install --user

On headless servers, prefer the system service. A user service only survives logout and reboot if lingering is enabled for that account:

sudo loginctl enable-linger <linux-user>

Verify the service

nmem service status
nmem status

To confirm exactly which build is running, print the build SHA:

nmem-server --build-info

The same value appears in GET /health/details (API key required) under .build_sha, so you can verify a deployment over the network or from a script.

Activate Your License

nmem license activate <license-key>        # Email is usually inferred from the key
nmem license status    # Verify activation
nmem license renew     # Refresh this device later if authorization expires

If email inference fails, run nmem license activate <license-key> <email> explicitly.

Open the Web App

Print a browser login link:

nmem key --show-login

Open the link on the device you want to connect. It signs you in directly, works once, and expires in a minute; run the command again whenever you need a fresh link. On older versions the link carries the API key itself, and both link forms keep working.

If your current build does not support --show-login yet, use:

nmem key

then open the web app in your browser and paste the printed key. On the default setup, the address is usually:

http://127.0.0.1:14242/app

On a headless server, your browser is usually on another computer. Use the exact URL and port that nmem key --show-login prints.

If you need an SSH tunnel, forward that same port:

ssh -L <port>:127.0.0.1:<port> <server>

Then open the login link in your browser. If it has expired, run the command again for a fresh one, or open the web app and paste the API key instead.

Download the Search Index Model

nmem models download
nmem models status     # Verify installation

This downloads the Search Index Model for hybrid search (~500 MB). Only needed once.

When you run headless, use these two commands as your quick search-health check:

  • nmem status: shows whether search is ready, rebuilding is needed, or Mem is only filling metadata in the background
  • nmem models status: shows the model state plus the current search-index action, if any

GET /health/details (API key required) carries the same signal for scripts and remote checks. Two fields matter:

  • embedding.mode is remote, local-gguf, or local-hash-fallback. The hash-fallback value means no real embedder is configured, so semantic search is degraded while keyword search still works. That is the signal to set a remote provider or download the local model.
  • search_index.reindex_pending is true when the search index is stale, usually after the embedding identity changes (a new provider or model).

The server never blocks boot to rebuild. It starts immediately and serves keyword (FTS) search while the index catches up, so a stale index fails soft to keyword results rather than erroring. Trigger the rebuild when you are ready, from Settings → Memory Processing → Search or with POST /search-index/reindex. If you would rather rebuild eagerly on boot, set NMEM_BOOT_AUTO_REINDEX=1 before starting the server.

Configure the LLM Provider

A remote LLM is required on Linux (no on-device LLM support):

nmem config provider set anthropic \
  --api-key sk-ant-xxx \
  --model claude-sonnet-4-20250514

nmem config provider test    # Verify connection

Supported providers include anthropic, openai, gemini, xai, deepseek, minimax, zai, moonshot, ollama, openrouter, and OpenAI-compatible endpoints.
See the full provider matrix and caveats: LLM Providers.

Enable Background Intelligence

nmem config settings set backgroundIntelligence true
nmem config settings set autoDailyBriefing true

Quick foreground test instead of systemd

If you do not want to install a systemd service yet:

nmem serve

Keep that terminal open. Then use a second terminal for nmem license ..., nmem models ..., and nmem config ....

Running as a systemd Service

For production deployments, use nmem service install to set up a background systemd service that automatically starts on boot:

# Install, enable, and start as your normal Linux user
sudo nmem service install --service-user <linux-user>

# If you are running sudo directly from that Linux user, Mem can usually infer it
sudo nmem service install

# Custom host/port
sudo nmem service install --service-user <linux-user> --host 0.0.0.0 --port 8080

For a system service, Mem should run as your normal Linux user, not as root. If sudo cannot infer the right account, pass --service-user <linux-user>. For a user service, run nmem service install --user directly as that user without sudo. If you want a user service to survive logout and reboot, also run sudo loginctl enable-linger <linux-user> once. If your VPS is intentionally root-only and you log in as root directly, nmem service install can still use /root consistently.

If you previously ran older builds as root, some files under ~/.config/co.nowledge.mem.desktop/ may still be owned by root. In that case, license actions, provider changes, or Access Anywhere settings can fail until you fix ownership for the Linux user that runs the service. Recent builds now show the exact path when this happens. A typical repair looks like:

sudo chown -R <linux-user>:<linux-user> ~/.config/co.nowledge.mem.desktop
sudo chown -R <linux-user>:<linux-user> ~/.local/share/NowledgeGraph

If you use custom XDG_CONFIG_HOME or XDG_DATA_HOME, repair those locations instead.

Managing the Service

nmem service status           # Show service status
nmem service stop             # Stop the service
nmem service start            # Start the service
nmem service uninstall        # Stop, disable, and remove
journalctl -u nmem -f         # Follow service logs (user-level service: journalctl --user -u nmem -f)

Add --user to any nmem service command if you installed a user-level service.

serve vs service

nmem servenmem service install
Runs inForeground (current terminal)Background (systemd)
Stops whenCtrl+C or terminal closesnmem service stop or system shutdown
Starts on bootNoYes (auto-enabled)
Best forTesting, developmentProduction deployments

Data Location

All data (graph database, search index, version metadata) is stored in a single directory:

~/.local/share/NowledgeGraph/
├── nowledge_graph_v2.db/   # KuzuDB graph database
├── search_index/           # LanceDB vector + BM25 index
└── db_version.json         # Schema version tracking

The server resolves this path automatically using XDG_DATA_HOME (defaults to ~/.local/share). To use a custom location, set the NMEM_APP_DATA environment variable to the directory that holds nowledge_graph_v2.db before starting the server:

export NMEM_APP_DATA=/mnt/data/NowledgeGraph
nmem serve

Upgrading from an older version

Older versions stored data in ./data/ relative to the working directory. After upgrading, the server will auto-detect legacy data and print migration instructions. If your data seems missing, see Troubleshooting: Missing data after upgrade below.

Remote Access

By default, nmem serve listens on 127.0.0.1 only. That is enough for:

  • nmem commands on the server itself
  • the built-in web app on the same local URL (by default http://127.0.0.1:14242/app)

If you bind to 0.0.0.0 or another non-loopback address, Mem requires an API key for other machines. The key is auto-generated when needed, and you can print it again at any time with:

nmem key
# or
nmem key --show-login

--show-login also prints a single-use browser login link: open it on the device you want to connect and it signs you in. Each link works once and expires in a minute; older versions embed the key in the link instead.

Once the server is reachable, connect clients through the highest-level surface they support: native connectors first, then plugin settings or nmem config, and only then direct MCP when no better dedicated path exists. The main exception today is Codex, where the dedicated package already bundles local MCP and remote deployments should override that endpoint in Codex config.

# On the server
nmem serve
nmem key

Install the standalone CLI on remote machines:

pip install nmem-cli
# or
uv pip install nmem-cli

Then configure the connection. The recommended persistent setup is:

nmem config client set url http://your-server:14242
nmem config client set api-key nmem_...

That writes ~/.nowledge-mem/config.json for this machine. If you only need a temporary shell session, use environment variables instead:

Temporary shell override
export NMEM_API_URL=http://your-server:14242
export NMEM_API_KEY="nmem_..."
nmem status
nmem m search "query"

Priority: CLI flags > env vars > config file > defaults.

Important for transcript-backed thread save

Commands like nmem t save --from claude-code, grok, gemini-cli, or codex still read local agent session files on the client machine running that agent. Pointing nmem at a remote server changes where the normalized data is uploaded, not where session discovery happens.

To disable authentication (not recommended for production):

NMEM_LAN_AUTH=disabled nmem serve

Security

API key authentication is enabled by default for connections from other machines. Localhost browser access can also require a key if you enable localhost auth. For additional security, restrict access via firewall rules or use Access Mem Anywhere with a Cloudflare tunnel.

Interactive TUI

For an interactive terminal experience, use the TUI:

nmem tui

The TUI provides a full settings management interface including license activation, LLM configuration, and knowledge processing toggles.

It is bundled in the Docker image too. On a container deployment, run it inside the container:

docker compose exec -it mem nmem tui

It also includes Access Anywhere controls in Settings, and the same screen can reveal the current API key plus the local web login URL. That makes it practical to complete the /app login flow even on a headless server.
Full guide: Access Mem Anywhere.

If your server network blocks UDP/QUIC and Access Anywhere fails to come online, force Cloudflare transport to HTTP/2 before restarting Mem:

export TUNNEL_TRANSPORT_PROTOCOL=http2

Configuration Reference

Environment Variables

VariableDefaultDescription
NMEM_API_URLhttp://127.0.0.1:14242Server URL for CLI commands
NMEM_API_KEY-API key for authenticated requests
NMEM_APP_DATAPlatform data dirOverride the full Mem graph/data root. Use this for isolated recovery or test boots only when you intentionally want a separate data directory.
NMEM_DISABLE_APP_DATA_HEAL0Set to 1/true for isolated recovery or test boots. This disables legacy data/config rescue so the server does not read or copy from the normal production locations.
NMEM_SERVER_ADDR127.0.0.1:14242Server bind address and port (nmem serve --host / --port set it)
NMEM_LAN_AUTH-Set to disabled to skip authentication

If you start nmem-server manually against a copied data directory, set both NMEM_APP_DATA and NMEM_DISABLE_APP_DATA_HEAL=1. The automatic legacy-data rescue is meant for normal app upgrades, not forensic/sandbox boots.

CLI Commands Summary

CommandDescription
nmem serveStart the server (default: same machine only)
nmem service installInstall and start as a systemd service
nmem service statusShow systemd service status
journalctl -u nmem -fFollow service logs
nmem service stop / startStop or start the service
nmem service uninstallRemove the systemd service
nmem statusCheck server health
nmem license activate <key> [email]Activate license (email is usually inferred)
nmem license renewRefresh or renew this device authorization
nmem models downloadDownload Search Index Model
nmem config provider set <p> --api-key <k>Configure LLM provider
nmem config provider testTest LLM connection
nmem config settingsShow processing settings
nmem config settings set <key> <value>Update a setting
nmem tuiInteractive terminal UI
nmem keyPrint the current API key
nmem key --show-loginPrint a single-use browser login link plus the API key
# APT package updates
sudo apt-get update
sudo apt-get install --only-upgrade nowledge-mem

Troubleshooting

Missing data after upgrade

Older versions (before 0.7) stored the database in ./data/ relative to the directory you ran nmem serve from. The current version stores data in the standard location (~/.local/share/NowledgeGraph/). If your memories disappeared after upgrading, your data is likely still on disk, just in the old location.

Find your old data

Search common locations where the old database may be:

find / -name "nowledge_graph*.db" -type d 2>/dev/null

Typical locations include:

  • ~/data/nowledge_graph.db, if you ran nmem serve from your home directory
  • /data/nowledge_graph.db, if the systemd service ran from / (system service without WorkingDirectory)
  • /path/where/you/ran/nmem/data/nowledge_graph.db, any other working directory

Move to the standard location

# Stop the server first
nmem service stop        # if using systemd
# or Ctrl+C              # if running in foreground

# Create the standard directory if needed
mkdir -p ~/.local/share/NowledgeGraph

# Move your database and related files
mv /old/path/data/nowledge_graph*.db* ~/.local/share/NowledgeGraph/
mv /old/path/data/search_index ~/.local/share/NowledgeGraph/  2>/dev/null
mv /old/path/data/db_version.json ~/.local/share/NowledgeGraph/  2>/dev/null

# Restart the server
nmem serve               # or: nmem service start

Verify recovery

nmem m search "test"     # Search for your memories
nmem status              # Check server health

Starting with the current version, nmem serve prints the database path at startup. This makes it easy to verify which location is being used. If legacy data is detected in ./data/, the server prints migration instructions automatically.

Next Steps

On this page