> For the complete documentation index, see [llms.txt](https://docs.lumia.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.lumia.org/run-a-node/zknode/run-a-local-validium-node.md).

# Run a local validium node

**Who this is for:** operators deploying their own Lumia Prism node from a fresh Linux host. This is the deployment tutorial referenced from [RPC node overview](https://app.gitbook.com/s/chmhPiVNAafGw48c4oU2/run-a-node/rpc-node/rpc-node-overview) and [zkNode overview](https://app.gitbook.com/s/chmhPiVNAafGw48c4oU2/run-a-node/zknode/zknode-overview): it's the same permissionless, self-hosted validium execution node under both names; see the naming note on the zkNode overview page.

**Prerequisites:**

* A Linux x86\_64 host meeting [hardware requirements](https://app.gitbook.com/s/chmhPiVNAafGw48c4oU2/run-a-node/hardware-requirements)
* Docker Engine with Compose v2
* An Ethereum L1 RPC endpoint

### Steps

{% stepper %}
{% step %}
**Prepare the host**

Install base packages, Docker, and a firewall; confirm your clock is synced and you have enough free disk before starting:

{% code title="host-prep.sh" %}

```bash
sudo apt-get update && sudo apt-get install -y git curl jq tar chrony ufw
curl -fsSL https://get.docker.com | sudo sh
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw enable
df -h /
```

{% endcode %}
{% endstep %}

{% step %}
**Get the deployment repository**

{% code title="clone-and-configure.sh" %}

```bash
git clone <repository-url>
cd <repository-directory>
cp .env.example .env
```

{% endcode %}
{% endstep %}

{% step %}
**Configure the network**

Set your L1 RPC endpoint and confirm the chain identity matches Lumia mainnet's chain ID from [`/reference/networks`](https://app.gitbook.com/s/chmhPiVNAafGw48c4oU2/reference/networks-and-endpoints): do not retype network values here; pull them from that page.

Sanity-check your L1 endpoint answers before proceeding:

{% code title="check-l1-endpoint.sh" %}

```bash
curl -s -X POST -H 'Content-Type: application/json' \
  --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' "<L1_RPC_URL>" | jq -r .result
# expect 0x1 for Ethereum mainnet
```

{% endcode %}
{% endstep %}

{% step %}
**Bootstrap from a snapshot**

{% hint style="warning" %}
Always verify the snapshot's checksum before extracting it, and abort if the check fails: don't run against a corrupted or tampered dataset.
{% endhint %}

{% code title="bootstrap-snapshot.sh" %}

```bash
curl -fL -C - -o snapshot.tar.gz "<snapshot-url>"
echo "<published-sha256>  snapshot.tar.gz" | sha256sum -c
mkdir -p data && tar -xzf snapshot.tar.gz --strip-components=1 -C data
```

{% endcode %}

The exact snapshot URL and checksum change over time: get the current ones from the repository your operator's guide points you to, not from a static copy in this doc.
{% endstep %}

{% step %}
**Start the node**

{% code title="docker-compose-up.sh" %}

```bash
docker compose up -d
docker compose logs -f
```

{% endcode %}
{% endstep %}
{% endstepper %}

### Verify it worked

Run these checks. Your node is synced only when all of them pass:

{% code title="verify-sync.sh" %}

```bash
# Chain identity: compare against the chain ID in /reference/networks
curl -s -X POST -H 'Content-Type: application/json' \
  --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' \
  http://127.0.0.1:8545 | jq -r .result

# Local head should advance between two calls a minute apart
curl -s -X POST -H 'Content-Type: application/json' \
  --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
  http://127.0.0.1:8545 | jq -r .result
```

{% endcode %}

### Troubleshooting

Common failures during this deployment are covered in depth on [Node troubleshooting](https://app.gitbook.com/s/chmhPiVNAafGw48c4oU2/run-a-node/node-troubleshooting): check there before assuming something is broken.
