Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,43 @@ lang: en-US
---
The performance of a full node will degrade when the storage size reaches a high volume. We suggest that the fullnode always keep light storage by pruning the storage.

### How to Prune

1. Stop the node, including the consensus client(morphnode) and the execution client(geth)
2. Run ```nohup geth snapshot prune-zk-state --datadir "$GETH_DB_DIR" > prune.log &```. It will take 5~7 hours to finish.
3. Start the node once it is done.
:::note
To prune a Geth node at least 200 GB of free disk space is recommended. This means pruning cannot be used to save a hard drive that has been completely filled. A good rule of thumb is to prune before the node fills ~80% of the available disk space.
:::

The hardware is important, **make sure the SSD meets: solid-state drive(SSD), 8k IOPS, 500 MB/S throughput, read latency < 1ms.**

### MPT Nodes (post-Jade Fork)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix heading level increment to satisfy markdown linting.

Line 13 and Line 25 should use ## (not ###) to avoid a heading-level jump (MD001).

Suggested diff
-### MPT Nodes (post-Jade Fork)
+## MPT Nodes (post-Jade Fork)

-### zkTrie Nodes (pre-Jade Fork)
+## zkTrie Nodes (pre-Jade Fork)

Also applies to: 25-25

🧰 Tools
🪛 markdownlint-cli2 (0.22.0)

[warning] 13-13: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/build-on-morph/developer-resources/node-operation/1-prune-state.md` at
line 13, The markdown has a heading-level jump (MD001): change the "### MPT
Nodes (post-Jade Fork)" heading and the other heading at the same section (the
second occurrence referenced at lines 25) from level 3 to level 2 by replacing
the leading "###" with "##" so both headings use "##" and restore proper heading
order to satisfy the linter.


After the [Jade Fork](./upgrade-node/0-jade-fork-overview.md), nodes run with `--morph-mpt` and use standard MPT state storage. Use the standard prune command:

:::note
To prune a Geth node at least 200 GB of free disk space is recommended. This means pruning cannot be used to save a hard drive that has been completely filled. A good rule of thumb is to prune before the node fills ~80% of the available disk space.
After switching to MPT storage, pruning is only supported after the node has synced **at least 128 blocks**. Do not attempt to prune immediately after migration.
:::

1. Stop the node, including the consensus client (`morphnode`) and the execution client (`geth`).
2. Run the prune command:
```bash
nohup geth snapshot prune-state --datadir "$GETH_DB_DIR" > prune.log &
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Prune commands may fail in source-built host setup due to bare geth invocation.

The doc uses nohup geth ..., but host run docs start geth via ./morph/go-ethereum/build/bin/geth (docs/build-on-morph/developer-resources/node-operation/full-node/2-run-on-host.md:117-129). Please either use the same explicit binary path here or state geth must be in PATH.

Also applies to: 36-36

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/build-on-morph/developer-resources/node-operation/1-prune-state.md` at
line 20, The prune command uses a bare geth invocation ("nohup geth snapshot
prune-state --datadir \"$GETH_DB_DIR\" > prune.log &"), which can fail if the
source-built binary isn't in PATH; update this line to either call the explicit
built binary used elsewhere (replace "geth" with the same explicit binary path)
or add a note that "geth must be in PATH" before the command, and apply the same
change to the other identical occurrence of the prune command in the file.

```
It will take several hours to finish.
3. Start the node once it is done.

### zkTrie Nodes (pre-Jade Fork)

:::caution
This section only applies to nodes still running with zkTrie state storage **before** migrating to MPT. Once you switch to an MPT node, the zkTrie prune command is no longer supported. See the [Jade Fork Overview](./upgrade-node/0-jade-fork-overview.md) for details.
:::

For nodes still running with zkTrie state storage, use the zkTrie-specific prune command:

1. Stop the node, including the consensus client (`morphnode`) and the execution client (`geth`).
2. Run the prune command:
```bash
nohup geth snapshot prune-zk-state --datadir "$GETH_DB_DIR" > prune.log &
```
It will take 5~7 hours to finish.
3. Start the node once it is done.



Original file line number Diff line number Diff line change
@@ -1,173 +1,208 @@
---
title: Run a full node with docker
title: Run a full node with Docker
lang: en-US
---

This guide will help you start a full node running in the docker container using [run-morph-node](https://github.com/morph-l2/run-morph-node)
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

## Quick Start
This guide will help you start a full node running in a Docker container using [run-morph-node](https://github.com/morph-l2/run-morph-node).

:::note
The instructions outlined below detail the procedure for running a full node on the mainnet. To set up and operate a **Hoodi node**, you need to follow the tutorial on [`sync node from snapshot`](#sync-node-from-snapshot).
:::
New deployments use **MPT** (Merkle Patricia Trie) state storage by default.

### Recommended Versions

1. Clone the dockerfile repository
| Component | Image |
|-----------|-------|
| geth | `ghcr.io/morph-l2/go-ethereum:2.2.1` |
| node | `ghcr.io/morph-l2/node:0.5.2` |

## Quick Start

### 1. Clone the repository

```bash
git clone https://github.com/morph-l2/run-morph-node.git
cd run-morph-node/morph-node
```
2. Run the following command

### 2. Check the geth image version

Make sure the `geth` service in `morph-node/docker-compose.yml` uses the latest recommended image:

```yaml
image: ghcr.io/morph-l2/go-ethereum:2.2.1
```

If your local checkout uses an older tag, update it before starting the node.

### 3. Prepare the MPT environment overrides

The Docker MPT flow uses `.env_mpt` as an override on top of `.env` for mainnet or `.env_hoodi` for Hoodi.

Example `.env_mpt`:

```bash
cd morph-node
make run-node
# MPT-specific overrides
GETH_ENTRYPOINT_FILE=./entrypoint-geth-mpt.sh

# Use the published MPT snapshot names for the target network
MAINNET_MPT_SNAPSHOT_NAME=mpt-snapshot-20260312-1
HOODI_MPT_SNAPSHOT_NAME=mpt-snapshot-20260312-1
```

The command `make run-node` takes the `../mainnet` as your node's **Home** directory by default. There will be two folders in the **Home** directory named `geth-data` and `node-data`, serving as data directories for the execution client and consensus client of the Morph node, respectively.
:::caution
For MPT nodes, the snapshot name **must** use the `mpt-snapshot-*` prefix. Do not use the standard `snapshot-*` name here.
:::

This command will also generate the `secret-jwt.txt` file under **Home** directory for the authentication during RPC calls between the execution client and consensus client.
### 4. Download and decompress the MPT snapshot

## Advanced Usage
<Tabs>
<TabItem value="mainnet" label="Mainnet">

With the [Quick Start](#quick-start) guide above, you can quickly start a node using the default configuration files. However, we also support customizing the node's data directory and parameter settings.
```bash
make download-and-decompress-mainnet-mpt-snapshot
```

### Customizing Data Directory
The host directory paths that are mounted by the Docker container are specified in the ```morph-node/.env``` file.
This downloads from:

```js title="morph-node/.env"
// HOME folder for morph node
MORPH_HOME=../mainnet
// Flag indicates the network for execution client.
MORPH_FLAG=morph
// Location of the jwt file for the authentication between clients
JWT_SECRET_FILE=${MORPH_HOME}/jwt-secret.txt
// The entrypoint shell script for start execution client
GETH_ENTRYPOINT_FILE=./entrypoint-geth.sh
// The snapshot name for Morph node
MAINNET_SNAPSHOT_NAME=snapshot-20241218-1
```
https://snapshot.morphl2.io/mainnet/mpt-snapshot-20260312-1.tar.gz
```

</TabItem>
<TabItem value="hoodi" label="Hoodi">

......
```bash
make download-and-decompress-hoodi-mpt-snapshot
```

You have the flexibility to customize the directory paths as per your requirements.
This downloads from:

Please note that if you have customized the **HOME** directory of your node, you need to copy the necessary configuration files to this directory. Specifically, you should copy the `node-data` and `geth-data` from `./mainnet` to your **HOME** directory.
```
https://snapshot.morphl2.io/hoodi/mpt-snapshot-20260312-1.tar.gz
```

:::note
For running a testnet node, the ```morph-node/.env_hoodi``` file should be used instead of the ```morph-node/.env``` file.
:::
</TabItem>
</Tabs>

### Customizing parameters
### 5. Set up the snapshot data

The default configuration required for mainnet node startup is located in the `./mainnet` directory, while the files under `./hoodi` directory is used for testnet node startup.
After downloading, place the decompressed data under the directory specified by `MORPH_HOME`. For example, if the snapshot folder is named `mpt-snapshot-20260312-1`:

```javascript
└── mainnet
├── geth-data
│   └── static-nodes.json
└── node-data
├── config
│   ├── config.toml
│   └── genesis.json
└── data
```bash
mv ./mpt-snapshot-20260312-1/geth ${MORPH_HOME}/geth-data
mkdir -p ${MORPH_HOME}/node-data/data
mv ./mpt-snapshot-20260312-1/data/* ${MORPH_HOME}/node-data/data
```

// for testnet nodes
└── hoodi
The directory structure should look like this:

```
└── ${MORPH_HOME}
├── geth-data
│   └── static-nodes.json
│ ├── static-nodes.json
│ └── geth
└── node-data
├── config
   ├── config.toml
   └── genesis.json
├── config.toml
└── genesis.json
└── data
```

If you wish to modify the Geth startup command, you can do so by editing the ```./morph-node/entrypoint-geth.sh``` file. For adjustments to the Tendermint-related configuration parameters, you should modify the `node-data/config/config.toml` file.
### 6. Run the node

## Sync node from snapshot
<Tabs>
<TabItem value="mainnet" label="Mainnet">

We suggest starting your node sync from a snapshot to speed up the process of syncing your node to the latest state.
```bash
make run-mainnet-mpt-node
```

### Clone the dockerfile repository
</TabItem>
<TabItem value="hoodi" label="Hoodi">

```bash
git clone https://github.com/morph-l2/run-morph-node.git
make run-hoodi-mpt-node
```

### Acquire the snapshot you need
</TabItem>
</Tabs>

The `morph-node/.env` configuration file in the repository you just cloned is designed for setting up the Morph node on the mainnet. By default, it is pre-configured to use the latest snapshot.
These commands start `geth` with the MPT entrypoint and run the consensus client using the selected environment.

If you need a historical snapshot, you must manually update the **SNAPSHOT_NAME** in the `morph-node/.env` file. (Note: For the **testnet**, the corresponding file is `morph-node/.env_hoodi`.)
## Advanced Usage

- **Fetch historical snapshot(Optional)**:

The historical snapshots are recorded in [snapshot-information](https://github.com/morph-l2/run-morph-node?tab=readme-ov-file#snapshot-information)
### Customizing the data directory

```js
// ...
The host directories mounted by Docker are controlled by the environment files.

MAINNET_SNAPSHOT_NAME={your expected snapshot name}
Example:

// ...
```
```bash
MORPH_HOME=../mainnet
MORPH_FLAG=morph
JWT_SECRET_FILE=${MORPH_HOME}/jwt-secret.txt
GETH_ENTRYPOINT_FILE=./entrypoint-geth-mpt.sh
```

- **Execute download and decompress the snapshot for your network**:

Run the following command to download and decompress the snapshot for your network:
If you customize `MORPH_HOME`, make sure the `geth-data` and `node-data` directories exist under that location and contain the required config files.

**For mainnet**:
For testnet, use `.env_hoodi` together with `.env_mpt`.

```
cd ./morph-node
make download-and-decompress-mainnet-snapshot
```
### Customizing parameters

**For testnet**:
To customize the execution client startup command, edit:

```
cd ./morph-node
make download-and-decompress-hoodi-snapshot
```
```
morph-node/entrypoint-geth-mpt.sh
```

To customize consensus-layer parameters, edit:

The command will assist you in downloading and decompressing the snapshot archive.
```
mainnet/node-data/config/config.toml # for mainnet
hoodi/node-data/config/config.toml # for Hoodi
```

### Set up the snapshot data
:::tip
The current reference MPT entrypoint still uses `--gcmode=archive` by default. If you want to run a pruned MPT node, customize the `geth` flags in `entrypoint-geth-mpt.sh` after validating your operational requirements.
:::

After downloading, locate the snapshot by placing the decompressed data files in the correct directory specified by the **MORPH_HOME** path in your `.env` file. Ensure the data files align with the node's expected structure to allow seamless synchronization.
## Verify the Node

For example, if the snapshot folder is named ```snapshot-20241218-1```,
- move the directory ```snapshot-20241218-1/geth``` to the ```${MORPH_HOME}/geth-data``` directory
- move the contents from ```snapshot-20241218-1/data``` to the ```${NODE_DATA_DIR}/data``` directory.
Check whether `geth` is connected to peers:

```
mv ./morph-node/snapshot-20241218-1/geth ${MORPH_HOME}/geth-data
mv ./morph-node/snapshot-20241218-1/data/* ${MORPH_HOME}/node-data/data
```bash
curl -X POST -H 'Content-Type: application/json' \
--data '{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":74}' \
localhost:8545
```

The folder structure will be like
Check the consensus client status:

```javascript
└── ${MORPH_HOME}
├── geth-data // data directory for geth
│   └── static-nodes.json
│   └── geth // directory from snapshot/geth
└── node-data // data directory for node
├── config
│   ├── config.toml
│   └── genesis.json
└── data // data directory from snapshot/node
```bash
curl http://localhost:26657/status
```

### 4. Run the Node
With the snapshot and configuration files ready, navigate to the `morph-node` folder under your cloned repository, and start the node using the provided command
When `catching_up` becomes `false`, the node has finished catching up.

```
make run-node
```
## MPT Snapshot Naming

For testnet, run
MPT snapshots use dedicated links and do **not** use the standard `snapshot-*` naming pattern.

| Type | Naming Pattern | Example |
|------|---------------|---------|
| Standard snapshot | `snapshot-YYYYMMDD-N` | `snapshot-20260312-1` |
| MPT snapshot | `mpt-snapshot-YYYYMMDD-N` | `mpt-snapshot-20260312-1` |

Use the dedicated MPT snapshot URL pattern:

```
make run-hoodi-node
https://snapshot.morphl2.io/<network>/mpt-snapshot-YYYYMMDD-N.tar.gz
```

Examples:

- `https://snapshot.morphl2.io/mainnet/mpt-snapshot-20260312-1.tar.gz`
- `https://snapshot.morphl2.io/hoodi/mpt-snapshot-20260312-1.tar.gz`
Loading
Loading