# Install on a server

Lumate on a Linux server for the whole office: one command installs it, it updates itself from OXS Cloud (or from an
offline bundle), backs itself up every day, and goes back by itself when an update does not start. For Lumate on one
Windows PC instead, see [Lumate Local](/docs/install-windows).

## What you need

| Item | Requirement |
|---|---|
| Server | Ubuntu 22.04 or 24.04, or Debian 12; x86_64; 2 vCPU, 4 GB RAM (8 GB recommended), 40 GB disk. Each service's memory is bounded (about 5.3 GB in all at most, the server's and the runner's 2 GB each; [Operations](/docs/operations#logs) says how to give the runner more) |
| Network | Ports 80 and 443 free on the server; outbound HTTPS to OXS Cloud, OpenAI, Anthropic and WhatsApp |
| Address | A public domain name pointing at the server (Let's Encrypt), or its name and address on the office network |
| Licence | Your licence key from the OXS portal (or activate in the browser after the setup) |
| Claude | The company's Claude account (signed in once on the server), or its Anthropic API key |
| OpenAI (for voice) | The company's own OpenAI API key |

The installer puts Docker Engine on the server when it is missing (from Docker's own repository, after asking).

## Install

On the server, as root:

```bash
curl -fsSL https://api.lumate.io/install.sh -o install.sh
sudo bash install.sh --key axk_yourlicencekey
```

To check the installer first (optional), run the steps below between these two lines.

### Checking the installer (optional)

`install.sh` is signed with Lumate's release key, and OXS Cloud publishes only a signed one. To check the downloaded
file yourself before running it, on the server:

```bash
curl -fsSLO https://api.lumate.io/install.sh.sig
printf -- '-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEA+bzBByJhjJ0huDTd2QQWNGRgQF52lo8TKCODtRzV4yo=\n-----END PUBLIC KEY-----\n' > agentx-release.pem
{ printf 'agentx-install-script-v1\0'; cat install.sh; } > install.signed
openssl pkeyutl -verify -pubin -inkey agentx-release.pem -rawin -in install.signed -sigfile install.sh.sig
```

It prints `Signature Verified Successfully`. Anything else means the file is not the one OXS signed: do not run it. The
installer then checks every release it downloads against the same key.

### What the installer asks

It asks for the address people open Lumate at. Answer with a public domain name (for example
`agentx.yourcompany.com`, whose DNS points at the server) for a Let's Encrypt certificate, or press Enter to use the
office network (the server's name and IP). The same choices as options, for an unattended install:

| Option | Meaning |
|---|---|
| `--domain NAME` and `--email ADDRESS` | A public domain name, with Let's Encrypt (the email gets Let's Encrypt's notices) |
| `--lan NAMES` | The office network's names and addresses, comma-separated: Lumate makes the office's own certificate authority |
| `--own-cert FILE --own-key FILE` | Your company's certificate and its key (PEM), for the addresses in `--lan` |
| `--channel beta` | Updates from the beta channel (stable is the default) |
| `--offline FILE` | Install from an offline bundle (no internet; see below) |
| `--yes` | Install Docker without asking |

What it does:
1. Checks the machine (the Linux, CPUs, memory, disk, ports 80/443, the way to OXS Cloud).
2. Fetches the release of your channel and checks it was signed with Lumate's release key. Then it checks the
   download's SHA-256.
3. Loads the images.
4. Writes `/opt/agentx`, with secrets made on the server (`.env`, readable by root only).
5. Starts Lumate and waits until it answers.

At the end it prints the setup link, which carries the setup token, and the token itself (for a lost link). Open the
link and make the first account with your email; then choose who sets up the company (you, or a manager you send a link
to). Given `--key`, the install is activated at its start: no OXS account is asked. See [First setup](/docs/first-setup).

### On the office network: trusting the certificate

With `--lan` (or Enter at the question), Lumate makes the office's own certificate authority. The installer prints
its SHA-256 fingerprint, and Settings → General shows it under the version. On each PC that opens Lumate:

1. Copy `/opt/agentx/ca.crt` from the server.
2. Compare its fingerprint with the one shown. On Windows: `certutil -hashfile ca.crt SHA256`.
3. Trust it for the current user: double-click it → Install Certificate → Current User → Trusted Root Certification
   Authorities.

Lumate Desk pins the server's certificate when it pairs, so it needs nothing more. The server's certificate lasts 825
days and is made again by itself a month before it ends; after that, pair Desk again once.

## What runs

`/opt/agentx/compose.yml` runs five services, each from the same version. All of them use the server's own network; only
Caddy listens beyond the server.

| Service | What it does |
|---|---|
| `caddy` | The web front: HTTPS on 443, redirects 80 |
| `server` | Lumate itself (127.0.0.1:8000 only) |
| `runner` | Runs the agents on the company's Claude account. It sets itself up: it enrols with the server once the first company exists |
| `whatsapp` | WhatsApp as a linked device (link a number in Settings → WhatsApp) |
| `updater` | Applies updates and undoes failed ones (it holds Docker's socket and nothing else) |

Claude Code signs in one of two ways, and every agent uses it:

- **The company's Claude account, signed in on the server**: on the server, run
  `sudo agentx claude-login`. It shows a link: open it on any device, sign in with the company's Claude account,
  approve, and type the code it gives back into the server's terminal. The sign-in is kept in the runner and renews
  itself; `sudo agentx claude-status` shows it, `sudo agentx claude-logout` ends it. Add `--console` to sign in with
  an Anthropic Console account (billed per use) instead of a Claude plan.
- **An Anthropic API key** (recommended for businesses: commercial terms) or a Claude sign-in token, in Settings →
  Runners → **Claude for the runners**. Owners and admins set it there; it is kept sealed and never shown back, and it
  comes first when both are set.

Settings → Runners shows, for each runner, whether its Claude Code is signed in.

## The desk phone (an IP phone on the office's PBX)

Lumate registers with the PBX as one extension (SIP over UDP 5060, audio as RTP) from the machine it runs on. Three ways
to reach the office's PBX:

| Where the server is | What to do |
|---|---|
| In the office network (it reaches the PBX) | Nothing more: Settings → Desk phone, **Connection runs on: This server**. The services use the server's own network, so the extension and its audio work as on a PC. |
| Outside the office (a data center, the internet) | A **linked PC** in the office carries the line (from 2.15.0): Lumate on an office PC, connected to this server and linked in Settings → Linked PCs; then Settings → Desk phone → **Connection runs on** that PC. The PC registers with the PBX and carries the calls' audio to the server over its own HTTPS connection (G.711, unchanged); no port is opened in the office and no VPN is needed. See [Connecting to a Lumate server](/docs/install-windows#connecting-to-a-lumate-server). |
| Outside the office, with a VPN to the office | The server reaches the PBX through the VPN: as in the office network. IT sets up the VPN. |

Through a linked PC the PC↔server round trip adds to each direction's audio (Settings → Linked PCs shows it); the
PC's jitter buffer is the same as on a desk phone in the office.

## The `agentx` command

On the server, as root:

| Command | What it does |
|---|---|
| `agentx status` | The version, the channel and each service |
| `agentx logs [server\|runner\|whatsapp\|caddy\|updater]` | The last log lines |
| `agentx backup` | A backup now, in `/opt/agentx/backups` |
| `agentx restore FILE` | Puts a backup's data back. Lumate stops meanwhile, and what changed since that backup is lost |
| `agentx update` | Installs the update Settings → Updates downloaded |
| `agentx update --bundle FILE` | Installs an offline bundle |
| `agentx rollback` | Goes back to the version before the last update |
| `agentx support-bundle` | Versions, settings without secrets and log lines for OXS support (no data) |
| `agentx claude-login` | Signs Claude Code in with the company's Claude account (a link to open, a code to type back) |
| `agentx claude-status` / `claude-logout` | Whether Claude Code is signed in; signs it out |
| `agentx uninstall` | Stops and removes Lumate. Its data stays unless you add `--delete-data` |

## Updates

Settings → Updates (the person who set up Lumate) shows:
- the version;
- the channel (stable or beta);
- automatic installs in the maintenance window (default 02:00–05:00, the company's time);
- what is offered, with its notes, and **Update now**.

Lumate looks every hour, downloads the update and checks it. It never installs during a call; the AI dialer pauses
meanwhile.

An update:
1. backs up the data first;
2. switches every service to the new version;
3. waits for it to answer.

If the new version does not start, Lumate goes back by itself, files and data, usually within a minute. That version
is then not installed again by itself; Update now can try it again. Settings → Updates then offers **Go back** to the
version before, kept on the server. When that version cannot read today's data, it takes the data from the backup made
before the update (a backup of today's is made first).

### Without internet: offline bundles

A server that cannot reach OXS Cloud is installed and updated from an offline bundle,
`AgentX-Server-<version>-offline.tar`, from OXS. It holds the images, their signed manifest and the installer. Use it in
one of three ways:
- install with `sudo bash install.sh --offline AgentX-Server-<version>-offline.tar`;
- update with `agentx update --bundle AgentX-Server-<version>-offline.tar`;
- upload it in Settings → Updates → Offline bundle.

Only a bundle signed with Lumate's release key is taken.

## Backups

Settings → Backups (the person who set up Lumate):
- **What is kept:** a backup every day at its hour (7 kept), one before every update (3 kept), and Back up now (10
  kept). Each can be downloaded.
- **What a backup holds:** the database and the shared files. It never holds the server's secrets, so also keep
  `/opt/agentx/.env` in a safe place. Without its `SECRETS_KEY`, the secrets stored in Lumate cannot be read.
- **Copy to a bucket:** each backup can also go to an S3-compatible bucket (AWS S3, Backblaze B2, Wasabi, MinIO…).
  Give the address, region, bucket, folder and an access key; the secret is kept sealed and never shown back.
- **Restoring:** only on the server, with `agentx restore`.

## Troubleshooting

| You see | Do |
|---|---|
| The installer stops at "ports 80 and 443 are in use" | Another web server runs on the server: stop it, or install Lumate on another server |
| The browser warns about the certificate (office network) | Trust `ca.crt` on that PC (above) |
| Settings → Updates says an update was undone | `agentx logs server` shows why the new version did not start; send `agentx support-bundle` to OXS |
| The runner says it waits for the team server | Create the first company (the setup), then it enrols by itself |
| Agents do not run | Settings → Runners: the runner is online and its Claude Code is signed in (`sudo agentx claude-login`, or an API key) |
