For the complete documentation index, see llms.txt. This page is also available as Markdown.

Run a Gravity Mainnet Public Full Node With Docker

Run a Gravity Mainnet (L1) Public Full Node with Docker. Covers image preparation, mainnet artifacts, PFN identity generation, pruning, startup, sync checks, and operational cleanup.

This guide walks you through running a Gravity Mainnet Public Full Node (PFN) with the gravity_node Docker image. A PFN syncs from an upstream public-network seed and can serve EVM JSON-RPC for applications, indexers, or internal services.

A PFN does not participate in consensus, does not hold validator stake, and does not require validator invite access.

Placeholders. Commands below use <YOUR_...> placeholders. Replace each value before running. Never commit generated identities, private keys, .env files, rendered node config, logs, or node databases to version control.

Prerequisites

  1. Docker and Docker Compose v2. Production nodes should run on Linux. Docker Desktop on macOS is useful for local validation, but it handles host networking differently from Linux.

  2. Local command-line tools. Install just, envsubst from GNU gettext, jq, curl, nc, and lsof.

  3. The Gravity SDK repository. The Docker image and config templates live in gravity-sdk.

    git clone https://github.com/Galxe/gravity-sdk.git
    cd gravity-sdk
  4. Mainnet genesis.json and waypoint.txt. These artifacts pin the exact chain you are joining. Download the canonical files from gravity-sdk/genesis/mainnet.

  5. An upstream public-network seed. The current public PFN seed is shown below.

  6. SSD/NVMe storage. Chain data grows with uptime. Budget well above the current chain size.

1. Build or Load the Docker Image

From the gravity-sdk repository root:

TAG=$(git rev-parse --short HEAD)

DOCKER_BUILDKIT=1 docker build --network=host \
  -f docker/gravity_node/Dockerfile \
  -t gravity_node:${TAG} \
  --build-arg CARGO_PROFILE=release \
  .

If your operator package provides a prebuilt image, load or pull that image instead and set IMAGE_TAG to its tag in later commands.

2. Prepare the Docker Workspace

Edit .env:

The container reads node config from ./config and stores chain data in Docker volumes.

3. Prepare Mainnet Artifacts

From docker/gravity_node:

Copy these artifacts into the Docker config directory:

4. Gather Seed Information

At the moment, public internet access is intended for the mainnet RPC/PFN fleet. Other validator and VFN hosts should be treated as private/internal unless the Gravity team explicitly shares invite-only seed information.

Node
Host
Public-network seed port
Peer ID
Network public key

rpc-1

mainnet-rpc-p2p-1.gravity.xyz

6180

38013b46c21388c3fd08ab32b86b478b3109125566d63c2da8fdc941dc474077

234aee14677a3d2198208ea72ca5e95ed75520df27f01f0c36220303ff78642f

Before using the seed, verify from your node host that the public-network port is reachable:

Use the current public PFN seed when rendering PFN_SEEDS_BLOCK in the Docker config section below:

5. Generate a PFN Identity

Create a minimal cluster config file for identity generation, for example cluster/local-pfn-docker.toml:

The Docker flow uses this TOML only to generate node identity material. It does not read ports, seeds, base_dir, or data_dir from the TOML during container startup. Docker runtime storage is controlled by the volume or bind mount in the start command, and by the container paths rendered in the next section.

Generate the PFN identity:

The generated identity.yaml contains private node identity material. Keep it on the runtime host only.

6. Render Container Config

The container sees config at /gravity/config and data at /gravity/data, so the rendered files must use container paths, not host paths.

DATA_DIR, STORAGE_DIR, and LOG_DIR are intentionally separate:

To place data on a specific host disk, mount that host path to /gravity/data. To place logs on a specific host disk, mount that host path to /gravity/logs. Do not change the TOML data_dir for Docker runtime storage.

From docker/gravity_node:

If you do not want transaction-lookup pruning, do not set PRUNE_TRANSACTIONLOOKUP_DISTANCE, and render reth_config.json from the non-prune template instead:

Verify the rendered config:

Expected reth_config.json behavior:

  • chain points to /gravity/config/genesis.json;

  • gravity_node_config points to /gravity/config/public_full_node.yaml;

  • datadir points to /gravity/data/data/reth;

  • log.file.directory points to /gravity/logs/execution_logs/;

  • when pruning is enabled, prune.transactionlookup.distance is 10064.

7. Pruning Mode

prune_transactionlookup_distance = 10064 starts reth with transaction-lookup pruning enabled. This keeps recent transaction-hash lookup data while allowing older lookup indexes to be pruned.

Use a value greater than or equal to 10064 for production PFN/RPC nodes. Treat smaller values as test-only and reject them during config review.

Use this pruning mode when you want lower execution database growth and do not need arbitrary old eth_getTransactionByHash lookups from this node.

If you omit prune_transactionlookup_distance, the generated PFN reth config uses archive-style transaction lookup behavior and keeps historical lookup indexes instead of pruning them. That is simpler for indexers or debugging flows that need old transaction hashes, but it uses more disk over time.

Do not set prune_transactionlookup_distance = 0 to disable pruning. A distance of 0 is still a pruning mode and can prune transaction lookup data aggressively. To run without transaction-lookup pruning, leave the field out.

8. Optional: Warm Start From a Snapshot or Existing Node

A new Docker PFN can sync from genesis, but that may take a long time on an established chain. To warm start, load the snapshot into the Docker data volume before the first node start.

If the Docker PFN has already started once, stop the container and remove the old data volume before importing a snapshot. Do not merge snapshot files into an already-initialized database.

The Docker container mounts its data volume at /gravity/data. The chain databases must live under /gravity/data/data, so extract snapshot contents into that data subdirectory.

Option A: Download the Public Mainnet Data Snapshot

Gravity publishes daily mainnet PFN data snapshots in the public bucket. Pick the latest available date and download it to your node host:

The snapshot tar contains database directories such as consensus_db/, quorumstoreDB/, and reth/ at the archive root. It does not contain an outer data/ directory.

For the Linux compose flow, load the snapshot into the compose data volume:

For the macOS docker run flow, load the snapshot into the explicit named volume used by the start command below:

After extraction, the Docker data volume should contain:

Option B: Copy From an Existing Node You Control

If you already run a trusted RPC/PFN, you can copy only the chain databases from that node:

Then load /tmp/pfn-data.tar into the Docker data volume with the same compose or docker run extraction pattern above. Mount /tmp as /snapshot and replace the extraction command with:

Do not copy rand_db or secure_storage.json from another node. Those files carry node-specific randomness or safety state and should not be reused.

9. Start the PFN

Make sure the selected host ports are free:

On Linux, use Docker Compose:

The compose file uses network_mode: host because p2p ports need predictable advertised addresses.

On Docker Desktop for macOS, host networking behaves differently. For local validation from the macOS host, use explicit port publishing:

10. Verify Sync

Query the local Docker PFN:

Compare with the public RPC:

Follow logs:

Confirm the prune config was accepted:

11. Stop, Restart, or Reset

For the Linux compose flow, stop the container but keep chain data:

Restart:

Delete the local PFN database and start from zero again:

For the macOS docker run flow, stop the container but keep chain data:

Delete the local PFN database and start from zero again:

Only remove Docker volumes when you intentionally want to delete the node database.

Files to Keep Out of Version Control

Do not commit generated runtime files:

  • docker/gravity_node/.env;

  • docker/gravity_node/config/*;

  • cluster/output/<YOUR_NODE_ID>/config/identity.yaml;

  • Docker volumes such as gravity-data, gravity-logs, gravity_node_local_pfn_data, and gravity_node_local_pfn_logs;

  • node databases and logs.

The reusable materials are the public guide and SDK templates. Each operator should generate their own identity and runtime config.

Last updated

Was this helpful?