This recipe describes how to prepare a fresh machine to run a headless Logos Storage node. It is written for a human operator or an AI agent that can SSH into the target machine and execute administrative commands.
The first section is system-independent. The second section gives the concrete Ubuntu 24.04 setup used for the Linode test node.
## Goal
Set up a machine that:
- Runs Logos Storage as a non-root service user.
- Keeps the REST API bound to localhost only.
- Exposes only the P2P and discovery ports publicly.
- Can be administered over SSH using key-based login.
- Starts the node automatically on boot using the host service manager.
## Target Runtime Shape
| Purpose | Default Used Here | Protocol | Exposure |
|---|---:|---|---|
| SSH | `22` | TCP | Restricted to operator IP |
| P2P listen | `8070` | TCP | Public |
| Discovery | `8090` | UDP | Public |
| REST API | `8080` | TCP | Localhost only |
The storage node command should look conceptually like:
```bash
storage \
--data-dir=<data-dir> \
--listen-port=8070 \
--disc-port=8090
```
Do not pass `--api-bindaddr=0.0.0.0` unless there is a deliberate reason to expose the API. The default API bind address is `127.0.0.1`.
## Generic Setup Steps
1. Provision a machine.
Choose a machine with enough resources for the intended workload. For running the node, a small machine can work. For compiling on the machine, prefer at least 2 vCPU and 2-4 GB RAM. A 1 vCPU / 1 GB RAM machine can build, but slowly and may need extra swap.
2. Configure firewall rules.
Inbound rules:
| Purpose | Protocol | Port | Source |
|---|---:|---:|---|
| SSH | TCP | `22` | Operator IP only, if possible |
| Storage P2P | TCP | `8070` | Public IPv4/IPv6 as needed |
| Storage Discovery | UDP | `8090` | Public IPv4/IPv6 as needed |
Do not open `8080/TCP` publicly. Access the API over SSH tunneling.
3. Create a non-root service user.
Create a dedicated user, for example `storage`. The node process should run as this user, not as `root`.
4. Configure SSH access.
Install the operator public SSH key for the service/admin user. Verify login works before disabling root login. Then harden SSH:
```text
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
```
5. Install build/runtime prerequisites.
Install a C/C++ toolchain, `git`, `cmake`, `curl`, `make`, `bash`, and runtime libraries required by the build. If building from source, install Nim `2.2.10`, preferably through `choosenim`.
6. Clone and build Logos Storage.
Clone `https://github.com/logos-storage/logos-storage-nim.git`, initialize submodules, and build:
```bash
make update
make NIMFLAGS="-d:disableMarchNative"
```
Use low parallelism on small machines:
```bash
make -j1 NIMFLAGS="-d:disableMarchNative"
```
`-d:disableMarchNative` is recommended for Linux amd64 release/test artifacts to avoid leaking build-machine CPU choices into the binary and to avoid known GCC/secp256k1 x86_64 asm failures.
7. Install the binary.
Install the built binary somewhere stable, for example:
```text
/opt/logos-storage/storage
```
Keep source checkout and runtime data separate.
8. Create the data directory.
Use a dedicated persistent data directory owned by the service user, for example:
```text
/var/lib/logos-storage
```
9. Create a service.
Use the platform service manager to run the node as the non-root service user, restart on failure, and start on boot.
10. Verify.
Verify:
- Service is running.
- TCP `8070` listens on all addresses.
- UDP `8090` listens on all addresses.
- TCP `8080` listens only on `127.0.0.1`.
-`GET http://127.0.0.1:8080/api/storage/v1/peerid` returns a peer ID locally.
- External TCP connectivity to `8070` works.
## Ubuntu 24.04 Example
This example assumes:
- Ubuntu 24.04 LTS.
- Initial SSH access as `root`.
- Desired user: `storage`.
- Public IP: replace `SERVER_IP` with the host IP.
UDP reachability is harder to verify with a simple shell one-liner. Confirm the firewall rule exists and inspect node logs for discovery startup and advertised `/udp/8090` addresses.