> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tape.network/llms.txt
> Use this file to discover all available pages before exploring further.

# Storage Node Setup

export const RunForm = ({path, source, children}) => {
  const url = `https://form.typeform.com/to/jJlpMc8r#path=${path}&source=${source}`;
  return <a href={url}>{children}</a>;
};

This guide takes you from a bare Linux machine to a registered Tapenet storage node that
syncs, serves its assigned spools, and earns TAPE. You'll want to be comfortable with a
shell and a service manager; root is only needed where your distribution requires it
for firewall changes. What a node actually does is covered on the
[storage nodes page](/protocol/architecture/storage-nodes); this page is about running
one.

<Info>
  Joining the public network as an operator starts with the staking program.
  <RunForm path="tapenet" source="storage-node">Fill out the form</RunForm> and we'll help you
  get set up.
</Info>

## Prerequisites

* A Linux machine (x86\_64) with about 4 TiB of disk, 16 GB of RAM, and a connection of at least 500 Mbps.
* A reliable Solana RPC endpoint. Bring your own provider or node, the same way you would for any serious Solana workload.
* SOL for transactions and enough TAPE to stake, held by the node's identity keypair.
  See [Tapenet funding](/tapenet/access#fund-a-node).
* Inbound connectivity on the port your node will serve peers on.

## Install

[Install Tapedrive](/install) on the machine that will run the node.

## Keys

A node needs three keys, and one command generates all of them plus a starter configuration file:

```bash theme={null}
tape-node keygen --out ~/.tape --name my-node
# wrote keys and node.yaml to /home/you/.tape
```

That writes four files:

* `identity.json`: the node's Solana keypair. This is its on-chain identity and fee
  payer. On Tapenet, give it a small amount of Solana devnet SOL for its
  transactions. [Tapenet setup](/tapenet/access) covers the rest.
* `bls.json`: the key the node votes and certifies with in its [spool group](/protocol/architecture/spool-groups).
* `tls.json`: the key the node presents to peers. Node-to-node traffic is mutually authenticated, and peers pin this key from the node's registration.
* `node.yaml`: a starter configuration, already pointing at the generated keys.

You can also reuse an existing Solana keypair as the identity if you prefer to manage it with the Solana CLI:

```bash theme={null}
solana-keygen new --outfile ~/.tape/identity.json
solana config set --url devnet # the public network runs on Solana devnet
```

## Configuration

The config lives at `~/.tape/node.yaml` by default. The starter file works with placeholders filled in; the sections you'll actually touch:

```yaml theme={null}
node:            # identity: paths to identity.json, bls.json
solana:          # your RPC endpoint and the deployed program addresses
network:         # the address this node advertises to peers
http:            # plaintext listener and ingress limits
https:           # the mTLS peer listener and the tls.json path
store:           # RocksDB paths and capacity
recovery:        # repair worker caps
logging:         # log level and format
metrics:         # optional Prometheus endpoint
genesis_preset:  # devnet (Tapenet), mainnet (future), or localnet
```

The `http` and `https` sections are separate listeners on purpose: one is the plaintext listener, the other is the mutually-authenticated peer side. The recovery and ingress settings are the knobs that shape resource use under load; the defaults are sensible and you can leave them alone on a first run.

## Register and stake

Registration is enforced by the protocol rather than an operator allow-list. Before
continuing, fund the identity generated above and check that its TAPE balance covers
your intended stake. Registration takes three commands signed by that identity:

```bash theme={null}
tape-admin node register \
  --identity ~/.tape/identity.json \
  --bls ~/.tape/bls.json \
  --tls ~/.tape/tls.json \
  --address node1.example.com:4040 \
  --name my-node

tape-admin node stake --identity ~/.tape/identity.json --amount 1000

tape-admin node join-committee --identity ~/.tape/identity.json
```

The `--address` is what peers will dial, so it has to be reachable from the internet. If you move the node to a new host later, updating it is one transaction: `tape-admin node set-address`.

Registration is also where you set your pool's commission (`--commission-bp`), the cut you take from delegators' rewards. [Token economics](/protocol/architecture/token-economics) covers how earnings flow.

Two timing expectations, so nothing surprises you: stake activates over two epochs, and the node starts receiving spool assignments once it's active. Leaving works the same way in reverse; unstaking is as permissionless as joining.

## Firewall

Open inbound TCP on the service port so gateways and peer nodes can reach you. Reachable does not mean public: peer traffic is mutually authenticated, and your node serves data only to staked peers ([the access rules](/protocol/architecture/storage-nodes)).

## Run

```bash theme={null}
tape-node --config ~/.tape/node.yaml
```

On first start the node bootstraps itself: it replays snapshot tapes to rebuild network state, then follows the chain live. There is no manual sync step and no state to import ([how bootstrap works](/protocol/architecture/tape-replay)).

<Warning>
  The local store is recoverable but not disposable. If you wipe it, the node has to re-bootstrap and recover every one of its spools from group peers, which takes time and bandwidth. Treat the storage paths with care.
</Warning>

### systemd

```ini theme={null}
[Unit]
Description=Tapedrive storage node
After=network-online.target

[Service]
ExecStart=/usr/local/bin/tape-node --config /home/tape/.tape/node.yaml
Restart=on-failure
TimeoutStopSec=60

[Install]
WantedBy=multi-user.target
```

`Restart=on-failure` pairs well with how the node is built: it prefers a clean exit over limping in a degraded state, and a restart resumes exactly where it left off ([the design](/protocol/architecture/storage-nodes)).

## Metrics and health

Build with the `metrics` cargo feature (the repository's make targets do) and point a Prometheus scraper at `/v1/metrics` on the HTTP listener ([telemetry](/tools/telemetry) lists every identifier). Four things are worth paging on:

```text theme={null}
# Falling behind the chain
tape_node_ingest_lag_slots > 300

# Ingest fully stalled: no blocks processed at all
rate(tape_node_blocks_processed_total[10m]) == 0

# Spool repair escalating instead of recovering cleanly
rate(tape_node_repair_escalations_total[15m]) > 0

# Running out of disk (tune the floor to your volume)
tape_store_disk_available_bytes < 50 * 1024 * 1024 * 1024
```

## Automated deployment

Running more than a couple of nodes? The repository's Ansible playbooks and provisioning CLI automate this whole guide; they're what we run our own fleet with.
