# Deployment

A self-contained Navi module for a server: dockerized PostgreSQL + the Navi
API server under systemd + `navi-code` in PATH. One command, SSH-only access,
web UI off by default.

## Deploy

Two commands from zero to a working module:

```bash
ssh server
git clone -b deploy <repo-url> navi-1 && cd navi-1
bash deploy/install.sh
```

What `install.sh` does (idempotent — safe to re-run, e.g. after `git pull`):

1. Checks prerequisites: Docker, and a Python ≥ 3.11.
   If the system has none (Ubuntu 18.04 ships 3.6, 22.04 ships 3.10 — and
   the system python must never be replaced), the script fetches a
   standalone CPython build into `.python/` inside the repo — self-contained,
   needs only glibc ≥ 2.17, so it runs on any distro, old or new. The
   downloaded tarball is kept next to the repo root and reused on re-runs;
   for an offline server, drop the tarball next to `install.sh` beforehand
   and it will be picked up instead of downloading. Same for the docker
   compose plugin: if the host doesn't have `docker compose` (18.04's docker
   packages predate it), the script installs the compose v2 binary itself
   into `/usr/local/lib/docker/cli-plugins/`.
2. Provisions `.env` — on the `deploy` branch it already ships with the
   deployment defaults (web UI off, auth off, Ollama Cloud, profile
   `navi_code`); the script generates the DB password in place of the
   `CHANGEME` placeholder.
3. Starts dockerized PostgreSQL (pgvector image, `restart: always`, bound to
   `127.0.0.1:5432`, data in the `navi-pgdata` docker volume) and installs
   the `vector` + `pg_trgm` extensions Navi's DDL expects.
4. Builds `.venv` and installs navi — the `navi-server` and `navi-code` entry
   points.
5. Writes and enables the systemd unit `navi.service` (`Restart=always`):
   the server lives from installation — starts on boot, restarts on crash.
6. Waits for `/health` to answer, then symlinks `navi-code` and `navi-server`
   into `/usr/local/bin`.

After the install finishes, fill in the one remaining secret and restart:

```bash
$EDITOR .env            # OLLAMA_API_KEY=<your Ollama Cloud key>
sudo systemctl restart navi
navi-code               # terminal client, ready to work
```

## What the default deployed state looks like

| Piece | State |
|---|---|
| Navi API server | systemd `navi.service`, `Restart=always`, starts on boot, binds `127.0.0.1:8000` |
| PostgreSQL | docker container `navi-postgres` (pgvector image), `restart: always`, bound to `127.0.0.1:5432`, data in the `navi-pgdata` volume |
| Web UI (`/`, `/assets`, `/admin`, debug panels, navi_ui MCP) | **off** (`NAVI_WEBCLIENT_ENABLED=false`) |
| Auth | **off** (`NAVI_AUTH_ENABLED=false`) — trusted single-server module, the API listens on localhost only |
| Terminal client | `navi-code` symlinked into `/usr/local/bin`, talks to `http://localhost:8000` |
| LLM | Ollama Cloud (`OLLAMA_HOST=https://ollama.com`), model priority lists come from the profile configs |

## Branch layout

- `master` — the full project, unconfigured, with all deployment machinery
  (`deploy/`, the `NAVI_WEBCLIENT_ENABLED` / `NAVI_HOST` / `NAVI_PORT` flags,
  the `navi-server` launcher).
- `deploy` — identical to master except for a committed `.env` with the
  deployment defaults filled in. Deploying = `git clone -b deploy`.

## Re-enabling the web panel later

Nothing is removed — the webclient and its code are all in the tree:

```bash
# in .env:
NAVI_WEBCLIENT_ENABLED=true
NAVI_UI_MCP_ENABLED=true
sudo systemctl restart navi
```

For remote browser access, tunnel or reverse-proxy to the API port; auth is
off by default, so keep it behind SSH or enable `NAVI_AUTH_ENABLED` first.

## Day-2 operations

```bash
systemctl status navi          # server supervision
journalctl -u navi -f          # live logs
sudo docker compose -f deploy/docker-compose.yml --env-file .env ps
sudo docker exec -it navi-postgres psql -U navi -d navi
```

Updating: `git pull && sudo systemctl restart navi` (the install script is
idempotent — re-running it after a pull also refreshes the venv).

## Files

- `install.sh` — everything above, in one command
- `docker-compose.yml` — the postgres container
- `env.template` — copied to `.env` on first install; the `deploy` branch
  carries a filled-in copy as its only diff from master