--- id: first-server title: Add your first server sidebar_label: Add your first server --- Enrolling a machine means running one command on it. The control plane issues a short-lived token, the install script fetches the agent and writes a config, and the machine registers itself. ## 1. Create the enrolment In the UI, go to **Servers → Add server**. That calls `POST /api/servers/new`, which generates a server ID and a pre-registration token and hands back a ready one-liner. :::warning The token is single-use and lives one hour It is the only credential in the flow, and it is spent the moment the agent calls `Register`. If you paste it somewhere and come back tomorrow, create a new enrolment instead — nothing is lost by doing so. ::: ## 2. Run the one-liner ### Linux ```bash curl -fsSL "https://vantage.example.com/install?server_id=&token=" | bash ``` Run it as root. The script: 1. Detects architecture — `x86_64` and `aarch64` only; anything else exits. 2. Asks the Gitea API for the newest `agent/v*` release. 3. Downloads the binary and `checksums.txt`, and **verifies the SHA-256**, aborting on a mismatch. 4. Installs to `/usr/local/bin/vantage-agent`, mode `0755`. 5. Writes `/etc/vantage/config.yaml` (directory `0700`, file `0600`) containing the server ID, the pre-registration token and the gRPC host. 6. Writes `/etc/systemd/system/vantage-agent.service` with `Restart=always`, and runs `systemctl enable --now vantage-agent`. ### Windows ```powershell irm "https://vantage.example.com/install.ps1?server_id=&token=" | iex ``` Run from an elevated PowerShell. The agent is registered as a service through NSSM, with the config at `%ProgramData%\vantage\config.yaml`. There is also an MSI built by CI if you would rather deploy that. :::info Windows agents are second-class on purpose They register, heartbeat, run workflow steps and report inventory. They do **not** manage `authorized_keys` — the key subsystem is Linux-only, and a Windows agent stops after the heartbeat portion of the poll. ::: ## 3. Watch it come up The server appears immediately as `pending`. Within one poll interval — 30 seconds — it flips to `active`. On the machine: ```bash systemctl status vantage-agent journalctl -u vantage-agent -f ``` What happens on that first run: ``` 1. Load /etc/vantage/config.yaml 2. pre_reg_token present → Register() → save agent_token, clear pre_reg_token 3. Reconnect with the permanent token 4. Start: command stream · hourly update check · inventory · monitors 5. Enter the SyncKeys poll loop ``` After registration the config no longer contains the pre-registration token; it contains a permanent agent token instead. The control plane stores only the SHA-256 of that token, never the token itself. ## 4. Confirm it works Open the server's detail page. Within a minute or two you should see: - Status `active`, with a recent last-seen timestamp. - Inventory — CPU, memory, swap, partitions, kernel. Metrics refresh every 30 seconds; the full static snapshot every 15 minutes. - Pending OS updates, checked hourly. ## If it does not appear | Symptom | Cause | | --- | --- | | Script exits at "Unsupported architecture" | Not amd64 or arm64 | | "Checksum mismatch!" | Interrupted download, or a proxy rewriting the body. Re-run | | "Could not determine latest agent version" | The host cannot reach `gitea.hostxtra.co.uk`, or no `agent/v*` release exists | | Service runs, server stays `pending` | The machine cannot reach `GRPC_HOST`. Test it from that machine | | Registers once then goes `offline` | Reachable for `Register` but not for the poll — usually a firewall that permits the initial connection but drops the long-lived one | A server is marked `offline` when its last-seen time passes the threshold; that sweep runs every two minutes, so allow for it before concluding anything. ## Next - [Assign an SSH key](../vantage/ssh-keys.md) - [Run a workflow](../vantage/workflows.md) - [Claim a Free licence](./claim-free-licence.md)