---
title: Node Installation
slug: node-installation
createdAt: 2026-11-10T21:08:28.169Z
---

A node joins OctaSpace with a single command and an enrollment key. One key can enroll as many machines as you like, and the key itself sets the services and prices every new node starts with.

## How it works

An enrollment key is a permission to create nodes in your account. You issue it in CUBE (**Hosting → Add a node**) and pass it to the installer on the machine. A key looks like `octa_ek_…`.

![](https://api.archbee.com/api/optimize/bdsKzi0GSJqADE8y4GkJt/DW1r_FvLBH0s6UuDHp1-s_image.png)

The key is not the node's password. On first start the machine generates its own key pair, and the private half never leaves the machine. The enrollment key is spent once, to create the node, and then the machine forgets it. So one key with 100 uses enrolls 100 machines, each with an identity of its own.

The old flow, where you copied a node token from the installer and entered it in CUBE by hand, is gone: the node appears in your account by itself as soon as the install finishes.

What happens during an install:

1. The installer sets up Docker, GPU container support and the `osn` agent.
2. The agent generates the node's keys and collects hardware fingerprints: motherboard, disk and GPU identifiers.
3. The agent presents the enrollment key. The platform checks it and creates the node with the services and prices the key carries.
4. The installer prints the node number, for example `7KQ4-M2XD-4`. The node is already listed in CUBE and starts its checks.

## Before you start

Check that the machine meets the hardware and software requirements listed on the [Overview](docId\:Xmpm0EubOeMnh0J_G4eHz) page. Install the NVIDIA driver before running the installer, and make sure the installer runs as root or with `sudo`.

The installer needs at least 200 GB for container data and leaves another 20% of free space to the system, so plan for about 250 GB free on the root partition. It keeps Docker data in a separate file, `/docker-data.img`, formatted as XFS: this is what makes per-container disk limits work. If you have already mounted your own disk at `/var/lib/docker`, the installer leaves it alone. To keep the installer away from disk layout entirely, set `SKIP_FS_CONFIG=1`.

On HiveOS, Docker fails to start when IPv6 is disabled in the kernel. Remove `ipv6.disable=1` from `GRUB_CMDLINE_LINUX_DEFAULT` in `/etc/default/grub`, run `update-grub` and reboot.

## Installing a single machine

All the machine needs is one command, and CUBE shows it ready to copy.

1. In CUBE, open **Hosting** and click **Add a node**.
2. Create a key: give it a name and choose services and prices (see the sections below). One key can serve all your machines.
3. Copy the install command and run it on the machine:

```bash
curl -fsSL https://install.octa.space | sudo bash -s -- octa_ek_XXXXXXXX…
```

4. Wait for the message that the node is enrolled, with its number. The install takes a few minutes, mostly downloading packages.
5. The **Add a node** window in CUBE shows **Node joined** and the node appears in your list. It then runs its checks and benchmarks (disk, network, AI Score) automatically and goes on the marketplace.

If you run the installer in a terminal without a key, it asks for one and waits up to 2 minutes. You can also pass the key in the `OCTA_ENROLLMENT_KEY` environment variable, which keeps it out of your shell history.

## Key settings

Every setting is fixed when the key is created. For different prices or a different expiry, create a new key.

| Setting        | What it sets                                                                        | Limits                                                                                 |
| -------------- | ----------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| Name           | A label for you: which batch or site the key is for, for example "DC Kyiv, 4090 x8" | Required, up to 64 characters                                                          |
| Number of uses | How many machines the key can enroll                                                | 1 to 10,000, or unlimited                                                              |
| Expiry         | The day the key works until (end of that day)                                       | At most one year ahead. If not chosen, one year from creation                          |
| Services       | What a new node rents out: Rental (compute), VPN, Rendering                         | Can be none: the node is then not rented out until you enable services in its settings |
| Prices         | The prices a new node starts with                                                   | See [Initial prices](#initial-prices)                                                  |

An account can hold up to 10 keys, expired and used-up ones included. Delete a key you no longer need to free a slot. Nodes it enrolled stay and keep working.

The key list shows how many times each key has been used (for example `3 / 10`), when it expires and whether it is active. While a key is active you can copy its install command again.

## Initial prices

The prices in a key are what a node goes on the marketplace with right after install, so a batch of identical machines needs no per-node setup. Prices are in US dollars (USDC), with up to 6 decimal places.

| Price   | Charged for                     | Minimum               |
| ------- | ------------------------------- | --------------------- |
| Base    | One hour of renting the machine | $0.0001               |
| Storage | One GB of disk per hour         | $0 (disk can be free) |
| Traffic | One GB of traffic               | $0.0001               |

Rules:

- Set all three prices or none.
- If the key enables any service, prices are required. Otherwise the node would rent out at minimum prices, close to free.
- A key without prices gives the node the minimums: $0.0001 for each item. Set your own prices in the node's settings before enabling services.
- Key prices apply only to new nodes. Nodes already enrolled, and nodes that come back after a reinstall, keep their own.
- After install you can change each node's prices on its **Configuration** tab.

Tip for mixed hardware: create a separate key for each configuration, for example "4090 x8" and "3090 x4", each with its own prices. The Base price covers the whole machine, so machines with a different number of GPUs should have different Base prices.

## Bulk deployment

For a fleet you need one key with enough uses and any tool that can run a command on every machine: Ansible, cloud-init, a script over SSH. Each machine gets its own identity and takes services and prices from the key.

How to prepare:

1. Issue a key for the batch: uses with a small margin for reinstalls, a short expiry covering the rollout, services and prices.
2. Put Ubuntu and the NVIDIA driver on the machines.
3. Run the installer on every machine with `OCTA_NONINTERACTIVE=1`. Without it the installer may stop and wait for someone to type a key.
4. Use the exit code to find machines that need attention (table below).
5. When the rollout is done, delete the key in CUBE or let it expire.

Running the installer again is safe. A machine that is already a node does not enroll again and does not spend a use of the key: the installer just updates the agent. So you can run the same playbook across the whole fleet as often as you like.

### Ansible

Keep the key in Ansible Vault. `no_log` keeps it out of the output.

```yaml
- hosts: octa_nodes
  become: true
  tasks:
    - name: Install OCTA node
      ansible.builtin.shell: |
        set -o pipefail
        curl -fsSL https://install.octa.space | bash
      args:
        executable: /bin/bash
      environment:
        OCTA_ENROLLMENT_KEY: "{{ octa_enrollment_key }}"
        OCTA_NONINTERACTIVE: "1"
      no_log: true
      register: octa_install
      failed_when: octa_install.rc != 0
```

### cloud-init

Suits cloud and virtual machines, and network autoinstall of Ubuntu. The NVIDIA driver must be installed before the installer runs.

```yaml
#cloud-config
runcmd:
  - apt-get update
  - apt-get install -y nvidia-driver-570
  - curl -fsSL https://install.octa.space | OCTA_ENROLLMENT_KEY=octa_ek_XXXXXXXX OCTA_NONINTERACTIVE=1 bash
```

### Installer exit codes

| Code | Meaning                                                          |
| ---- | ---------------------------------------------------------------- |
| 0    | Node installed and enrolled, or an already enrolled node updated |
| 2    | Not run as root                                                  |
| 3    | Unsupported Ubuntu release or architecture                       |
| 4    | Not enough disk space                                            |
| 5    | `/var/lib/docker` is not empty                                   |
| 6    | No enrollment key given                                          |
| 7    | Key rejected: mistyped, expired, deleted or used up              |
| 8    | Timed out waiting for enrollment, most likely no connectivity    |
| 9    | Failed to download the agent                                     |

## Reinstalling the OS and replacing hardware

After reinstalling the OS, run the installer again with a key from the same account. The platform recognises the machine by its hardware and returns your old node: same number, name, prices, settings and history. Nothing needs to be set up again.

How the machine is recognised:

- By the motherboard identifiers. This is the main signal, and a GPU swap does not get in the way.
- If the motherboard reports no identifiers, by the set of GPUs: at least half of the cards must match, counted both against the cards the machine has now and against the cards the node had before.
- When in doubt, the platform creates a new node instead of returning the old one. Renaming a node is easy; merging two different machines into one would be much worse.

Things to know:

- Returning an old node spends one use of the key, like enrolling a new one. Leave some margin of uses for reinstalls.
- A node can only be returned to the account it belongs to. Someone else's key will never take over your node.
- If a node with the same hardware is online right now, the machine is enrolled as a new node. This is how a cloned disk or a second identical machine is handled.
- A deleted node is never returned: the machine is enrolled as a new one.

## Ports and VPN

A node needs no inbound ports for compute rentals: traffic goes through a proxy edge in the region nearest to the node. Opening ports is required only for the VPN service.

For VPN:

- The machine needs a static public IP.
- The service port range from the node's settings must be reachable from the internet for both TCP and UDP. Behind NAT, forward the range on your router; if the host firewall drops incoming traffic, allow the range there.

The platform checks the ports itself from an edge server once the node is idle, and offers it for VPN only after the check passes. A failed check is retried every 30 minutes, so after fixing the router you do not have to do anything. A passed range is checked again every 4 hours. On top of that the platform starts a real VPN on the node from time to time and makes sure pages load through it.

## Monitoring

Once installed, a node can be monitored without CUBE. The agent serves a web dashboard at `http://<node-ip>:18888` with the node's state, GPUs, energy, containers and log. For a fleet, it also exports Prometheus metrics, and there is a ready-made Grafana dashboard to import. See [Node monitoring](docId\:xIZGASd9Q-vTiUYZXlJUQ) for details.

## Updating and removing

To update, run the same install command again. No key is needed: the machine is already a node.

```bash
curl -fsSL https://install.octa.space | sudo bash
```

To remove the agent from a machine:

```bash
systemctl stop osn
systemctl disable osn
rm -f /etc/systemd/system/osn.service
userdel -r octa
```

`userdel -r` also deletes the node's keys. If you install on this machine again later, it will come back as the same node (see [Reinstalling the OS](#reinstalling-the-os-and-replacing-hardware)). To remove the node from your account, delete it in CUBE.

## Key security

An enrollment key lets anyone who has it add machines to your account. It cannot be used to control existing nodes, read your data or withdraw funds.

- Set as few uses and as short an expiry as the job needs.
- Do not put a key into a public repository, chat or screenshot. Keep it in a secret store (Ansible Vault and the like).
- If a key leaks, delete it in CUBE. Nodes it already enrolled keep working.
- Watch the use counter of your keys: a use you do not expect means someone else has the key.
- The key is not kept on the machine after enrollment, so a node's disk falling into the wrong hands does not let anyone add new nodes.

## Troubleshooting

| What you see                              | What to do                                                                                                      |
| ----------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `No enrollment key`                       | Create a key in CUBE (**Hosting → Add a node**) and run the installer again with it                             |
| `No such enrollment key`                  | Check the key was copied in full                                                                                |
| `The enrollment key has expired`          | Create a new key                                                                                                |
| `The enrollment key has no uses left`     | Create a new key with more uses                                                                                 |
| `The enrollment key has been revoked`     | The key was deleted in CUBE. Create a new one                                                                   |
| `Not enough disk space`                   | Free up space or add a disk: 200 GB for Docker plus 20% for the system                                          |
| `/var/lib/docker is not empty`            | Move the old Docker data aside, or set `SKIP_FS_CONFIG=1` to keep the current layout                            |
| `Timed out waiting for enrollment`        | Check that the machine has internet access over HTTPS and run the installer again                               |
| The node is online but not rented for VPN | Check the port forwarding (see [Ports and VPN](#ports-and-vpn)). The node's page in CUBE shows the check result |

