> For the complete documentation index, see [llms.txt](https://services.luckyresearch.org/lucky-research-services/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://services.luckyresearch.org/lucky-research-services/mainet/celestia/installation.md).

# Installation

{% hint style="info" %}
**Network:** Celestia Mainnet Beta — chain-id `celestia`

**celestia-app / fibre:** `v10.5.0` (app version 10)

**Last updated:** October 30, 2026
{% endhint %}

### Hardware requirements

**Validator / consensus node** (pruned):

* Memory: **32 GB RAM**
* CPU: **32 cores** (must pass the [CPU benchmark](https://github.com/celestiaorg/celestia-app/blob/main/tools/cpu_requirements/README.md); GFNI + SHA-NI recommended)
* Disk: **2 TB NVMe**
* Bandwidth: **1 Gbps**
* OS: **Ubuntu 24.04 LTS** — the multiplexer build needs glibc **2.38+**, so Ubuntu 22.04 and older will not work

**Fibre server** (required for validators on v10):

* Memory: **32 GB RAM** minimum (64 GB recommended if you raise `max_connections`)
* A **separate disk** from celestia-app data
* Disk and bandwidth depend on your voting power: [Fibre requirements sheet](https://docs.google.com/spreadsheets/d/1P3k-KQrZxbRjRwIxWkJBNwgAFlFMJUdT7OupA_WoKa0/edit?gid=971673838#gid=971673838)
* OS: glibc **2.34+** (Ubuntu 22.04+ is fine for the Fibre binary)
* Running Fibre on its **own server in the same datacenter** as the validator is recommended

**Update if needed**

```bash
sudo apt update && sudo apt upgrade -y
```

## Install packages

```bash
sudo apt install curl tar wget aria2 lz4 clang pkg-config libssl-dev jq build-essential git make ncdu -y
```

**Install Go** (source builds require Go 1.26.6)

```bash
cd $HOME
ver="1.26.6"
wget "https://golang.org/dl/go$ver.linux-amd64.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "go$ver.linux-amd64.tar.gz"
rm "go$ver.linux-amd64.tar.gz"
echo "export PATH=\$PATH:/usr/local/go/bin:\$HOME/go/bin" >> $HOME/.bash_profile
source $HOME/.bash_profile
go version
```

## Install celestia-app

`make install` builds the **multiplexer** binary. Do not use the `standalone` build and do not use Cosmovisor.

```bash
cd $HOME
rm -rf celestia-app
git clone https://github.com/celestiaorg/celestia-app.git
cd celestia-app
git checkout tags/v10.5.0
make install

celestia-appd version
```

{% hint style="info" %}
Prefer prebuilt binaries? Download `celestia-app_Linux_x86_64.tar.gz` from the [v10.5.0 release](https://github.com/celestiaorg/celestia-app/releases/tag/v10.5.0) and verify it against `checksums.txt`.
{% endhint %}

## Init node

```bash
MONIKER="<YOUR_MONIKER>"
celestia-appd init "$MONIKER" --chain-id celestia
celestia-appd config set client chain-id celestia
celestia-appd config set client keyring-backend file
```

{% hint style="warning" %}
Do not use the `test` keyring backend on mainnet — it stores the key unencrypted on disk. Use `file` or `os`.
{% endhint %}

## Genesis - Seeds - Gas prices

```bash
# genesis
celestia-appd download-genesis celestia

# official seeds
SEEDS=$(curl -sL https://raw.githubusercontent.com/celestiaorg/networks/master/celestia/seeds.txt | tr '\n' ',')
sed -i -e "s/^seeds *=.*/seeds = \"$SEEDS\"/" $HOME/.celestia-app/config/config.toml

# minimum gas price
sed -i 's/^minimum-gas-prices *=.*/minimum-gas-prices = "0.002utia"/' $HOME/.celestia-app/config/app.toml
```

## Pruning - Indexer

```bash
# validator: keep a larger recent block history without going archival
sed -i 's/^pruning *=.*/pruning = "default"/' $HOME/.celestia-app/config/app.toml
sed -i 's/^min-retain-blocks *=.*/min-retain-blocks = 600000/' $HOME/.celestia-app/config/app.toml

# indexer
sed -i 's/^indexer *=.*/indexer = "null"/' $HOME/.celestia-app/config/config.toml
```

{% hint style="info" %}
Archive / RPC node: use `pruning = "nothing"`, `min-retain-blocks = 0` and `indexer = "kv"` instead (needs \~16 TB NVMe).
{% endhint %}

## gRPC (required for Fibre)

Fibre talks to the node over application gRPC and the privval gRPC endpoint. Both must be enabled — if `[grpc] enable = false`, `create-validator` and Fibre will fail.

```bash
# app.toml -> [grpc]
sed -i '/^\[grpc\]/,/^\[/ s/^enable *=.*/enable = true/' $HOME/.celestia-app/config/app.toml

# config.toml -> privval gRPC (use an IP literal, "localhost" is rejected)
sed -i 's|^priv_validator_grpc_laddr *=.*|priv_validator_grpc_laddr = "127.0.0.1:26669"|' $HOME/.celestia-app/config/config.toml

# config.toml -> rpc.grpc_laddr (required since v4)
sed -i 's|^grpc_laddr *=.*|grpc_laddr = "tcp://127.0.0.1:9098"|' $HOME/.celestia-app/config/config.toml

# add any missing settings shipped with the new binary
celestia-appd config sync --home $HOME/.celestia-app --dry-run
celestia-appd config sync --home $HOME/.celestia-app
```

If Fibre will run on a separate server, see **Option B** in the Fibre section below — the privval endpoint then needs mutual TLS.

**Create service**

```bash
sudo tee /etc/systemd/system/celestia-appd.service > /dev/null <<EOF
[Unit]
Description=celestia-appd
After=network-online.target

[Service]
User=$USER
ExecStart=$(which celestia-appd) start --home $HOME/.celestia-app
Restart=on-failure
RestartSec=10
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable celestia-appd
```

**Wallet**

```bash
celestia-appd keys add wallet
# or restore
celestia-appd keys add wallet --recover
```

Check validator address

```bash
celestia-appd keys show wallet --bech val -a
```

**Snapshot (quick sync)**

```bash
sudo systemctl stop celestia-appd

cp $HOME/.celestia-app/data/priv_validator_state.json $HOME/.celestia-app/priv_validator_state.json.backup
rm -rf $HOME/.celestia-app/data
mkdir -p $HOME/.celestia-app/data

cd $HOME
SNAP_NAME=$(curl -s https://snaps.qubelabs.io/celestia/ | egrep -o ">celestia.*tar" | tr -d ">")
aria2c -x 16 -s 16 -o celestia-snap.tar "https://snaps.qubelabs.io/celestia/${SNAP_NAME}"
tar xf celestia-snap.tar -C $HOME/.celestia-app/data/
rm celestia-snap.tar

mv $HOME/.celestia-app/priv_validator_state.json.backup $HOME/.celestia-app/data/priv_validator_state.json

sudo systemctl restart celestia-appd && sudo journalctl -u celestia-appd -f -o cat
```

Other providers and state sync: [Celestia snapshots guide](https://docs.celestia.org/operate/maintenance/snapshots).

Check sync

```bash
celestia-appd status 2>&1 | jq .sync_info.catching_up
```

If it is `false` => Create Validator

```bash
celestia-appd tx staking create-validator \
--amount=1000000utia \
--pubkey=$(celestia-appd tendermint show-validator) \
--moniker="<YOUR_MONIKER>" \
--identity="<KEYBASE_ID>" \
--chain-id=celestia \
--commission-rate=0.1 \
--commission-max-rate=0.2 \
--commission-max-change-rate=0.01 \
--min-self-delegation=1000000 \
--from=wallet \
--keyring-backend=file \
--fees=21000utia \
--gas=220000 \
-y
```

`--identity` is optional (your Keybase ID, used by explorers to show your logo). Remove the line if you don't use it.

## Fibre server

Fibre is a separate data availability service. On app version 10 every **bonded** validator is expected to run one: it receives blob shards from clients, stores them for the retention window and serves them back. Fibre never talks to your KMS — it asks the node's privval gRPC endpoint to sign.

```
          clients (always TLS, automatic)
                     |
                     v  :7980 (public, registered on-chain)
            +------------------+
            |   Fibre server   |
            +------------------+
   app gRPC :9090 |      | privval gRPC :26669
   (no TLS,       |      | (plaintext on loopback,
    keep private) v      v  mTLS when remote)
            +------------------+
            | celestia-appd    |
            | (validator)      |
            +------------------+
```

{% hint style="warning" %}
The Fibre host you register is public on-chain. If Fibre runs on the validator host, your validator's IP becomes public too — another reason to run Fibre on a separate server.
{% endhint %}

### 1. Pre-checks

```bash
# chain must be on app version 10
curl -s http://127.0.0.1:26657/abci_info | jq .result.response.app_version

# validator must be bonded (BOND_STATUS_BONDED)
celestia-appd query staking validator $(celestia-appd keys show wallet --bech val -a) -o json | jq .validator.status

# app gRPC must be enabled
grep -A3 '^\[grpc\]' $HOME/.celestia-app/config/app.toml
```

### 2. Install Fibre

The Fibre version must match the celestia-app release.

**From source** (on the Fibre host):

```bash
cd $HOME
rm -rf celestia-app
git clone https://github.com/celestiaorg/celestia-app.git
cd celestia-app
git checkout tags/v10.5.0
make build-fibre-server
sudo cp build/fibre /usr/local/bin/fibre
fibre version
```

**Or prebuilt binary:**

```bash
cd $HOME
curl -LO https://github.com/celestiaorg/celestia-app/releases/download/v10.5.0/fibre_Linux_x86_64.tar.gz
curl -LO https://github.com/celestiaorg/celestia-app/releases/download/v10.5.0/checksums.txt
sha256sum --ignore-missing --check checksums.txt
tar -xvf fibre_Linux_x86_64.tar.gz
sudo mv fibre /usr/local/bin/fibre
fibre version
```

### 3. Fibre home on a separate disk

```bash
# change the path to a mount on a different disk than celestia-app data
FIBRE_HOME=/mnt/fibre-data/.celestia-fibre
sudo mkdir -p $FIBRE_HOME && sudo chown -R $USER:$USER $FIBRE_HOME
echo "export FIBRE_HOME=$FIBRE_HOME" >> $HOME/.bash_profile
```

The config file lives at `$FIBRE_HOME/config/server_config.toml` and is created on the first start.

### 4. Signer connection

Pick **one** option.

#### Option A — Fibre on the same server (plaintext loopback)

Nothing extra to configure on the node — keep `priv_validator_grpc_laddr = "127.0.0.1:26669"` (set above). Use `127.0.0.1`, not `localhost`.

```bash
APP_GRPC="127.0.0.1:9090"
SIGNER_GRPC="127.0.0.1:26669"
```

#### Option B — Fibre on a separate server (mutual TLS, recommended)

Connect the two servers over a private network (VLAN or WireGuard) and use the validator's **private** IP below. Never expose ports 9090 or 26669 publicly — firewall them so only the Fibre server's private IP can connect.

**On the validator** — bind app gRPC to the private IP and create the certificates:

```bash
# replace with your validator's private IP
NODE_IP="<VALIDATOR_PRIVATE_IP>"
CERT_DIR=/etc/celestia/privval

# app gRPC on the private interface
sed -i "/^\[grpc\]/,/^\[/ s|^address *=.*|address = \"$NODE_IP:9090\"|" $HOME/.celestia-app/config/app.toml

# dedicated CA + server cert (node) + client cert (fibre)
sudo mkdir -p $CERT_DIR && sudo chown -R $USER:$USER $CERT_DIR && cd $CERT_DIR
openssl ecparam -genkey -name prime256v1 -out ca.key
openssl req -x509 -new -key ca.key -sha256 -days 3650 -subj "/CN=privval-ca" -out ca.crt

# server cert: the SAN must match the address Fibre dials
openssl ecparam -genkey -name prime256v1 -out server.key
openssl req -new -key server.key -subj "/CN=celestia-node" -out server.csr
printf "subjectAltName=IP:$NODE_IP\nextendedKeyUsage=serverAuth\n" > server.ext
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 825 -sha256 -extfile server.ext -out server.crt

# client cert for Fibre
openssl ecparam -genkey -name prime256v1 -out client.key
openssl req -new -key client.key -subj "/CN=fibre" -out client.csr
printf "extendedKeyUsage=clientAuth\n" > client.ext
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 825 -sha256 -extfile client.ext -out client.crt

chmod 600 *.key
```

Set the privval TLS settings in `$HOME/.celestia-app/config/config.toml` (all three files must be set together):

```toml
priv_validator_grpc_laddr = "<VALIDATOR_PRIVATE_IP>:26669"
priv_validator_grpc_cert_file = "/etc/celestia/privval/server.crt"
priv_validator_grpc_key_file = "/etc/celestia/privval/server.key"
priv_validator_grpc_client_ca_file = "/etc/celestia/privval/ca.crt"
```

Restart the node, then copy `ca.crt`, `client.crt` and `client.key` to the same folder on the Fibre server. Keep `ca.key` on the validator only.

```bash
sudo systemctl restart celestia-appd
# on the Fibre server first: sudo mkdir -p /etc/celestia/privval
scp /etc/celestia/privval/{ca.crt,client.crt,client.key} <user>@<FIBRE_PRIVATE_IP>:/etc/celestia/privval/
```

**On the Fibre server:**

```bash
APP_GRPC="<VALIDATOR_PRIVATE_IP>:9090"
SIGNER_GRPC="<VALIDATOR_PRIVATE_IP>:26669"
```

After the first start (step 6) creates `$FIBRE_HOME/config/server_config.toml`, set these keys at the top level of the file (above any `[section]`), then restart Fibre:

```toml
signer_grpc_address = "<VALIDATOR_PRIVATE_IP>:26669"
signer_grpc_ca_file = "/etc/celestia/privval/ca.crt"
signer_grpc_cert_file = "/etc/celestia/privval/client.crt"
signer_grpc_key_file = "/etc/celestia/privval/client.key"
```

{% hint style="danger" %}
Do not use `signer_grpc_allow_insecure` — anyone who can reach an unprotected signer can request signatures with your consensus key. Always point the signer at the **validator**, not a sentry.
{% endhint %}

Details: [privval TLS guide](https://github.com/celestiaorg/celestia-core/blob/v0.42.3/docs/guides/privval-grpc-tls.md).

### 5. Create the Fibre service

```bash
sudo tee /etc/systemd/system/fibre.service > /dev/null <<EOF
[Unit]
Description=Celestia Fibre server
After=network-online.target

[Service]
User=$USER
ExecStart=/usr/local/bin/fibre start \\
  --home $FIBRE_HOME \\
  --app-grpc-address $APP_GRPC \\
  --signer-grpc-address $SIGNER_GRPC \\
  --server-listen-address 0.0.0.0:7980
Restart=on-failure
RestartSec=10
TimeoutStopSec=120
LimitNOFILE=65535
MemoryMax=32G
OOMScoreAdjust=500

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable fibre
```

Open the public Fibre port:

```bash
sudo ufw allow 7980/tcp
```

### 6. Start Fibre

```bash
sudo systemctl start fibre && sudo journalctl -u fibre -f -o cat
```

The startup log shows the chain ID, addresses and storage backend. `creating signer` errors mean Fibre cannot reach `priv_validator_grpc_laddr`. `derived storage budget is 0` means the validator is not bonded or the node is still syncing.

From a machine **outside** your network, check the port is reachable:

```bash
nc -zv <your-fibre-host> 7980
```

### 7. Register the Fibre host

Register only after Fibre is running and reachable. The host is `host:port` (IP or DNS name, no `http://`).

```bash
celestia-appd tx valaddr set-host <your-fibre-host>:7980 \
--from=wallet --chain-id=celestia --keyring-backend=file --fees=21000utia -y

# verify (found: true)
celestia-appd query valaddr provider $(celestia-appd comet show-address)
celestia-appd query valaddr providers
```

Registration persists. Re-run `set-host` only when the address changes, or after the validator was jailed/unbonded for more than 7 days.

### 8. Health check

After registration the log should stop showing `server not ready`. Fibre exposes the standard gRPC health service on port 7980 (readiness: service `""`, liveness: `fibre-liveness`). With `grpc_health_probe` (from any machine):

```bash
grpc_health_probe -addr=<your-fibre-host>:7980 -tls -tls-no-verify                          # readiness
grpc_health_probe -addr=<your-fibre-host>:7980 -tls -tls-no-verify -service=fibre-liveness   # liveness
```

The `[health]` table in `server_config.toml` controls `check_interval` (10s), `probe_timeout` (3s) and `max_block_age` (2m).

### 9. Tuning (optional)

Worst-case RAM ≈ `max_connections × max_concurrent_streams × 132 MiB`. Defaults (16 × 13 ≈ 27 GiB) fit a 32 GB host. A single upload uses 16 connection slots, so on a 64 GB host raising `max_connections` keeps slots free for downloads:

```toml
# $FIBRE_HOME/config/server_config.toml
max_connections = 24
max_concurrent_streams = 13
```

Leave `min_upload_size` at its default (256 KiB) unless validators agree on a change. Restart Fibre after editing.

### Upgrading Fibre

Stop Fibre, then the node, replace both binaries with the same release, sync config, start the node, then Fibre:

```bash
sudo systemctl stop fibre && sudo systemctl stop celestia-appd
# replace celestia-appd and fibre binaries
celestia-appd config sync --home $HOME/.celestia-app --fibre-home $FIBRE_HOME --dry-run
celestia-appd config sync --home $HOME/.celestia-app --fibre-home $FIBRE_HOME
sudo systemctl start celestia-appd && sudo systemctl start fibre
```

Restarting Fibre rotates its TLS certificate automatically. Unknown keys in `server_config.toml` make Fibre fail at startup.

References: [Run a Fibre server](https://docs.celestia.org/operate/consensus-validators/fibre) · [Fibre README v10.5.0](https://github.com/celestiaorg/celestia-app/blob/v10.5.0/fibre/cmd/README.md)
