> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/graphprotocol/graph-node/llms.txt
> Use this file to discover all available pages before exploring further.

# Installation

> Complete installation guide for Graph Node - from Docker to building from source with all prerequisites and configuration options.

## Overview

Graph Node can be installed in several ways depending on your use case:

* **Docker (Recommended)**: Best for subgraph developers testing locally
* **Docker with existing services**: When you already have IPFS and PostgreSQL
* **From source**: For contributors and advanced users who need to modify Graph Node

<Note>
  Most subgraph developers should use the [Quickstart](/quickstart) guide which covers Docker setup. This page provides comprehensive installation details for all methods.
</Note>

## Method 1: Docker Compose (Recommended)

The easiest way to get started with Graph Node is using the pre-configured Docker Compose setup.

### Prerequisites

* Docker 20.10+ and Docker Compose v2.0+
* An Ethereum RPC endpoint (Infura, Alchemy, or local node)
* 8GB+ RAM (16GB recommended for Apple Silicon)
* 20GB+ free disk space

### Installation Steps

<Steps>
  <Step title="Clone the repository">
    ```bash theme={null}
    git clone https://github.com/graphprotocol/graph-node.git
    cd graph-node/docker
    ```
  </Step>

  <Step title="Configure Ethereum connection">
    Edit `docker-compose.yml` and update the `ethereum` environment variable:

    ```yaml theme={null}
    environment:
      postgres_host: postgres
      postgres_user: graph-node
      postgres_pass: let-me-in
      postgres_db: graph-node
      ipfs: 'ipfs:5001'
      ethereum: 'mainnet:http://host.docker.internal:8545'
      GRAPH_LOG: info
    ```

    Replace `http://host.docker.internal:8545` with your Ethereum node URL.
  </Step>

  <Step title="Start the services">
    ```bash theme={null}
    docker-compose up
    ```

    For production, use detached mode:

    ```bash theme={null}
    docker-compose up -d
    ```
  </Step>

  <Step title="Verify installation">
    Check that all services are running:

    ```bash theme={null}
    docker-compose ps
    ```

    Test the GraphQL endpoint:

    ```bash theme={null}
    curl http://localhost:8000/
    ```
  </Step>
</Steps>

### Docker Compose Configuration

The `docker-compose.yml` file defines three services:

#### Graph Node

```yaml theme={null}
graph-node:
  image: graphprotocol/graph-node
  ports:
    - '8000:8000'  # GraphQL HTTP
    - '8001:8001'  # GraphQL WebSocket
    - '8020:8020'  # Admin/Deploy
    - '8030:8030'  # Index node server
    - '8040:8040'  # Metrics
  depends_on:
    - ipfs
    - postgres
```

#### IPFS

```yaml theme={null}
ipfs:
  image: ipfs/kubo:v0.17.0
  ports:
    - '5001:5001'
  volumes:
    - ./data/ipfs:/data/ipfs:Z
```

#### PostgreSQL

```yaml theme={null}
postgres:
  image: postgres
  ports:
    - '5432:5432'
  command:
    [
      "postgres",
      "-cshared_preload_libraries=pg_stat_statements",
      "-cmax_connections=200"
    ]
  environment:
    POSTGRES_USER: graph-node
    POSTGRES_PASSWORD: let-me-in
    POSTGRES_DB: graph-node
    POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C"
  volumes:
    - ./data/postgres:/var/lib/postgresql/data:Z
```

### Data Persistence

Docker Compose stores data in `./data/` with two subdirectories:

* `./data/ipfs` - IPFS blocks and metadata
* `./data/postgres` - PostgreSQL database files

These persist across container restarts. To completely reset:

```bash theme={null}
docker-compose down -v
rm -rf data/
docker-compose up
```

## Method 2: Docker with Existing Services

If you already have IPFS and PostgreSQL running, you can run only the Graph Node container.

### Prerequisites

* PostgreSQL 12+ with the following extensions:
  * `pg_trgm`
  * `btree_gist`
  * `postgres_fdw`
* IPFS (Kubo) running and accessible
* Ethereum RPC endpoint

### Running Graph Node

```bash theme={null}
docker run -it \
  -p 8000:8000 \
  -p 8001:8001 \
  -p 8020:8020 \
  -p 8030:8030 \
  -p 8040:8040 \
  -e postgres_host=<POSTGRES_HOST> \
  -e postgres_port=5432 \
  -e postgres_user=<USER> \
  -e postgres_pass=<PASSWORD> \
  -e postgres_db=<DBNAME> \
  -e ipfs=<IPFS_HOST>:5001 \
  -e ethereum=mainnet:https://mainnet.infura.io/v3/YOUR_KEY \
  -e GRAPH_LOG=info \
  graphprotocol/graph-node:latest
```

<Tip>
  For Linux hosts connecting to services on the host machine, use `--network="host"` or your machine's IP address instead of `localhost`.
</Tip>

### Docker Environment Variables

| Variable        | Description         | Example                       |
| --------------- | ------------------- | ----------------------------- |
| `postgres_host` | PostgreSQL hostname | `postgres` or `192.168.1.100` |
| `postgres_port` | PostgreSQL port     | `5432`                        |
| `postgres_user` | Database user       | `graph-node`                  |
| `postgres_pass` | Database password   | `secure-password`             |
| `postgres_db`   | Database name       | `graph-node`                  |
| `ipfs`          | IPFS API endpoint   | `127.0.0.1:5001`              |
| `ethereum`      | Network and RPC URL | `mainnet:https://...`         |
| `GRAPH_LOG`     | Log level           | `info`, `debug`, `trace`      |

## Method 3: Building from Source

Building from source is necessary for Graph Node contributors or when you need to modify the code.

### Prerequisites

<Tabs>
  <Tab title="System Requirements">
    * **OS**: Linux, macOS, or Windows (WSL2)
    * **RAM**: 8GB minimum, 16GB recommended
    * **Disk**: 20GB+ free space
    * **CPU**: Multi-core processor recommended
  </Tab>

  <Tab title="Required Software">
    * **Rust**: Latest stable toolchain
    * **PostgreSQL**: Version 12 or higher
    * **IPFS**: Kubo (go-ipfs) latest version
    * **Protobuf Compiler**: protoc 3.x
    * **Ethereum Node**: Or RPC provider access
  </Tab>
</Tabs>

### Step 1: Install Rust

Graph Node requires the latest stable Rust compiler:

<CodeGroup>
  ```bash Linux/macOS theme={null}
  curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  source $HOME/.cargo/env

  # Install stable toolchain
  rustup install stable
  ```

  ```bash Windows (PowerShell) theme={null}
  # Download and run rustup-init.exe from https://rustup.rs/
  # Then:
  rustup install stable
  ```
</CodeGroup>

Verify installation:

```bash theme={null}
rustc --version
cargo --version
```

### Step 2: Install PostgreSQL

<CodeGroup>
  ```bash Ubuntu/Debian theme={null}
  sudo apt update
  sudo apt install postgresql postgresql-contrib libpq-dev
  sudo systemctl start postgresql
  sudo systemctl enable postgresql
  ```

  ```bash macOS (Homebrew) theme={null}
  brew install postgresql
  brew services start postgresql

  # Or use Postgres.app (recommended):
  # Download from https://postgresapp.com/
  ```

  ```bash Fedora/RHEL theme={null}
  sudo dnf install postgresql-server postgresql-contrib libpq-devel
  sudo postgresql-setup --initdb
  sudo systemctl start postgresql
  sudo systemctl enable postgresql
  ```

  ```bash Arch Linux theme={null}
  sudo pacman -S postgresql
  sudo -u postgres initdb -D /var/lib/postgres/data
  sudo systemctl start postgresql
  sudo systemctl enable postgresql
  ```
</CodeGroup>

### Step 3: Configure PostgreSQL

Create a database user and database for Graph Node:

```bash theme={null}
# Connect as superuser (usually 'postgres' or your username)
psql -U postgres <<EOF
create user graph with password 'your-password-here';
create database "graph-node" with owner=graph template=template0 encoding='UTF8' locale='C';
\c graph-node
create extension pg_trgm;
create extension btree_gist;
create extension postgres_fdw;
grant usage on foreign data wrapper postgres_fdw to graph;
EOF
```

<Note>
  On macOS with Postgres.app, use your username instead of `postgres`. On fresh Linux installations, you may need to `sudo -u postgres psql`.
</Note>

Set the database connection string as an environment variable:

```bash theme={null}
export POSTGRES_URL=postgresql://graph:your-password-here@localhost:5432/graph-node

# Add to ~/.bashrc or ~/.zshrc for persistence
echo 'export POSTGRES_URL=postgresql://graph:your-password-here@localhost:5432/graph-node' >> ~/.bashrc
```

Test the connection:

```bash theme={null}
psql $POSTGRES_URL -c "SELECT version();"
```

### Step 4: Install IPFS

<CodeGroup>
  ```bash Linux theme={null}
  wget https://dist.ipfs.tech/kubo/v0.17.0/kubo_v0.17.0_linux-amd64.tar.gz
  tar -xvzf kubo_v0.17.0_linux-amd64.tar.gz
  cd kubo
  sudo bash install.sh
  ipfs init
  ipfs daemon &
  ```

  ```bash macOS theme={null}
  brew install ipfs
  ipfs init

  # Start IPFS daemon
  ipfs daemon &

  # Or run as a service:
  brew services start ipfs
  ```

  ```bash Windows (WSL2) theme={null}
  wget https://dist.ipfs.tech/kubo/v0.17.0/kubo_v0.17.0_linux-amd64.tar.gz
  tar -xvzf kubo_v0.17.0_linux-amd64.tar.gz
  cd kubo
  sudo bash install.sh
  ipfs init
  ipfs daemon &
  ```
</CodeGroup>

Verify IPFS is running:

```bash theme={null}
curl http://localhost:5001/api/v0/version
```

### Step 5: Install Protobuf Compiler

<CodeGroup>
  ```bash Ubuntu/Debian theme={null}
  sudo apt install protobuf-compiler
  ```

  ```bash macOS theme={null}
  brew install protobuf
  ```

  ```bash Fedora/RHEL theme={null}
  sudo dnf install protobuf-compiler
  ```

  ```bash From Source theme={null}
  # Download from https://github.com/protocolbuffers/protobuf/releases
  PROTOC_ZIP=protoc-21.12-linux-x86_64.zip
  curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v21.12/$PROTOC_ZIP
  sudo unzip -o $PROTOC_ZIP -d /usr/local bin/protoc
  sudo unzip -o $PROTOC_ZIP -d /usr/local 'include/*'
  rm -f $PROTOC_ZIP
  ```
</CodeGroup>

Verify installation:

```bash theme={null}
protoc --version
```

### Step 6: Clone and Build Graph Node

<Steps>
  <Step title="Clone the repository">
    ```bash theme={null}
    git clone https://github.com/graphprotocol/graph-node.git
    cd graph-node
    ```
  </Step>

  <Step title="Install Rust dependencies">
    ```bash theme={null}
    rustup install stable
    ```
  </Step>

  <Step title="Build Graph Node">
    ```bash theme={null}
    cargo build --release
    ```

    <Warning>
      The first build can take 15-30 minutes and requires significant disk space (\~10GB for build artifacts).
    </Warning>
  </Step>

  <Step title="Verify the build">
    ```bash theme={null}
    ./target/release/graph-node --version
    ```
  </Step>
</Steps>

### Step 7: Run Graph Node

Start Graph Node with your configuration:

```bash theme={null}
export GRAPH_LOG=debug
export POSTGRES_URL=postgresql://graph:your-password@localhost:5432/graph-node

./target/release/graph-node \
  --postgres-url $POSTGRES_URL \
  --ethereum-rpc mainnet:https://mainnet.infura.io/v3/YOUR_PROJECT_ID \
  --ipfs 127.0.0.1:5001
```

<Note>
  Graph Node will print the ports it's listening on when it starts. The GraphQL HTTP server defaults to `http://localhost:8000`.
</Note>

### Ethereum RPC Configuration

The `--ethereum-rpc` argument format is:

```
NETWORK_NAME:[CAPABILITIES]:URL
```

**Examples:**

<CodeGroup>
  ```bash Basic theme={null}
  --ethereum-rpc mainnet:https://mainnet.infura.io/v3/YOUR_KEY
  ```

  ```bash Archive Node with Traces theme={null}
  --ethereum-rpc mainnet:archive,traces:https://your-archive-node.com
  ```

  ```bash Multiple Networks theme={null}
  --ethereum-rpc mainnet:https://mainnet.infura.io/v3/KEY \
  --ethereum-rpc sepolia:https://sepolia.infura.io/v3/KEY
  ```

  ```bash Local Hardhat Node theme={null}
  --ethereum-rpc mainnet:http://127.0.0.1:8545
  ```
</CodeGroup>

**Provider Capabilities:**

* `archive`: Full historical state (required for many subgraphs)
* `traces`: Supports `debug_traceBlockByNumber` (for call handlers)
* No capabilities: Regular full node

### Running as a System Service

For production deployments, run Graph Node as a systemd service:

```ini /etc/systemd/system/graph-node.service theme={null}
[Unit]
Description=Graph Node
After=network.target postgresql.service
Requires=postgresql.service

[Service]
Type=simple
User=graph
WorkingDirectory=/opt/graph-node
Environment="POSTGRES_URL=postgresql://graph:password@localhost:5432/graph-node"
Environment="GRAPH_LOG=info"
ExecStart=/opt/graph-node/target/release/graph-node \
  --postgres-url $POSTGRES_URL \
  --ethereum-rpc mainnet:https://mainnet.infura.io/v3/YOUR_KEY \
  --ipfs 127.0.0.1:5001
Restart=always
RestartSec=10

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

Enable and start the service:

```bash theme={null}
sudo systemctl daemon-reload
sudo systemctl enable graph-node
sudo systemctl start graph-node
sudo systemctl status graph-node
```

View logs:

```bash theme={null}
sudo journalctl -u graph-node -f
```

## Advanced Configuration

### Using a Configuration File

For complex setups (multiple chains, database sharding, multiple nodes), use a TOML configuration file:

```toml config.toml theme={null}
[store]
[store.primary]
connection = "postgresql://graph:password@localhost:5432/graph-node"
pool_size = 10

[chains]
ingestor = "block_ingestor_node"

[chains.mainnet]
shard = "primary"
provider = [
  { label = "mainnet", url = "https://mainnet.infura.io/v3/YOUR_KEY", features = ["archive", "traces"] }
]

[chains.sepolia]
shard = "primary"
provider = [
  { label = "sepolia", url = "https://sepolia.infura.io/v3/YOUR_KEY", features = [] }
]

[deployment]
[[deployment.rule]]
indexers = [ "index_node_0" ]
```

Run with config file:

```bash theme={null}
graph-node --config config.toml --node-id index_node_0
```

See the [Configuration](/configuration) page for complete details.

### Environment Variables

Graph Node behavior can be tuned with [environment variables](/environment-variables):

```bash theme={null}
# Logging
export GRAPH_LOG=info  # error, warn, info, debug, trace

# Ethereum
export ETHEREUM_POLLING_INTERVAL=500  # ms
export ETHEREUM_REORG_THRESHOLD=250   # blocks

# IPFS
export GRAPH_IPFS_TIMEOUT=60  # seconds

# GraphQL
export GRAPH_GRAPHQL_QUERY_TIMEOUT=300        # seconds
export GRAPH_GRAPHQL_MAX_COMPLEXITY=10000000
export GRAPH_GRAPHQL_MAX_FIRST=1000

# Database
export STORE_CONNECTION_POOL_SIZE=10
```

### Monitoring and Metrics

Graph Node exposes Prometheus metrics on port 8040:

```bash theme={null}
curl http://localhost:8040/metrics
```

Common metrics:

* `deployment_sync_progress` - Sync progress per subgraph
* `ethereum_chain_head_number` - Latest block number
* `query_execution_time` - Query performance

## Verifying Installation

Test your Graph Node installation:

<Steps>
  <Step title="Check GraphQL endpoint">
    ```bash theme={null}
    curl http://localhost:8000/
    ```

    Should return the GraphiQL interface HTML.
  </Step>

  <Step title="Check available subgraphs">
    ```bash theme={null}
    curl -X POST \
      -H "Content-Type: application/json" \
      -d '{"query": "{ indexingStatuses { subgraph chains { network } } }"}' \
      http://localhost:8000/graphql
    ```
  </Step>

  <Step title="Verify Ethereum connection">
    Check the logs for:

    ```
    Connected to Ethereum node at ...
    Starting block ingestor
    ```
  </Step>

  <Step title="Test IPFS">
    ```bash theme={null}
    curl http://localhost:5001/api/v0/version
    ```
  </Step>

  <Step title="Test PostgreSQL">
    ```bash theme={null}
    psql $POSTGRES_URL -c "SELECT COUNT(*) FROM subgraphs.subgraph;"
    ```
  </Step>
</Steps>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Build fails with 'error: linker `cc` not found'">
    **Solution**: Install build essentials

    ```bash theme={null}
    # Ubuntu/Debian
    sudo apt install build-essential

    # macOS
    xcode-select --install

    # Fedora/RHEL
    sudo dnf groupinstall "Development Tools"
    ```
  </Accordion>

  <Accordion title="PostgreSQL extension installation fails">
    **Symptoms**: `ERROR: could not open extension control file`

    **Solution**: Install PostgreSQL contrib package

    ```bash theme={null}
    # Ubuntu/Debian
    sudo apt install postgresql-contrib

    # macOS with Homebrew
    # Extensions are included by default

    # Fedora/RHEL
    sudo dnf install postgresql-contrib
    ```

    Then reconnect and create extensions.
  </Accordion>

  <Accordion title="IPFS not starting">
    **Symptoms**: `Connection refused` on port 5001

    **Solutions**:

    ```bash theme={null}
    # Check if IPFS is installed
    ipfs version

    # Initialize if needed
    ipfs init

    # Start daemon
    ipfs daemon

    # Check if port is in use
    lsof -i :5001
    ```
  </Accordion>

  <Accordion title="Out of memory during build">
    **Symptoms**: Build process killed or panics

    **Solutions**:

    * Increase swap space
    * Use `cargo build --release -j 2` to limit parallel jobs
    * Build on a machine with more RAM
    * Use pre-built Docker images instead
  </Accordion>

  <Accordion title="Graph Node crashes on startup">
    **Common causes**:

    1. **Database migration fails**: Check PostgreSQL logs
    2. **Can't connect to Ethereum**: Verify RPC URL
    3. **IPFS unreachable**: Ensure IPFS daemon is running
    4. **Port already in use**: Check if another instance is running

    ```bash theme={null}
    # Check for existing Graph Node process
    ps aux | grep graph-node

    # Check port usage
    lsof -i :8000
    lsof -i :8001
    lsof -i :8020
    ```
  </Accordion>

  <Accordion title="'postgres_fdw' extension error">
    **Symptoms**: `ERROR: could not load library... postgres_fdw`

    **Solution**: This usually means PostgreSQL development files are missing:

    ```bash theme={null}
    # Ubuntu/Debian
    sudo apt install postgresql-server-dev-14  # Match your PG version

    # macOS
    brew reinstall postgresql

    # Then reconnect and create the extension
    ```
  </Accordion>
</AccordionGroup>

## Platform-Specific Notes

### macOS

* Use [Postgres.app](https://postgresapp.com/) for the easiest PostgreSQL setup
* Homebrew installs work well for all dependencies
* Apple Silicon users should expect longer build times
* Graph Node Docker images are x86\_64 only; build locally for ARM64

### Linux

* Prefer system package managers for dependencies
* On `host.docker.internal` doesn't work; use `172.17.0.1` or `--network="host"`
* Ensure PostgreSQL accepts local connections in `pg_hba.conf`
* Increase file descriptor limits for production: `ulimit -n 65536`

### Windows (WSL2)

* All development should occur within WSL2, not native Windows
* Use Ubuntu 20.04+ or Debian for best compatibility
* Docker Desktop integration with WSL2 works well
* PostgreSQL should run inside WSL2, not as Windows service

## Performance Tuning

### PostgreSQL Configuration

For production, tune PostgreSQL settings in `postgresql.conf`:

```ini theme={null}
# Memory
shared_buffers = 4GB                # 25% of RAM
effective_cache_size = 12GB         # 75% of RAM
work_mem = 256MB
maintenance_work_mem = 1GB

# Connections
max_connections = 200

# Query planner
random_page_cost = 1.1              # SSD: 1.1, HDD: 4.0
effective_io_concurrency = 200      # SSD: 200, HDD: 2

# Logging
shared_preload_libraries = 'pg_stat_statements'
log_min_duration_statement = 1000   # Log slow queries > 1s
```

Restart PostgreSQL after changes:

```bash theme={null}
sudo systemctl restart postgresql
```

### Graph Node Optimization

```bash theme={null}
# Connection pooling
export STORE_CONNECTION_POOL_SIZE=25

# Ethereum batch size
export ETHEREUM_BLOCK_BATCH_SIZE=10

# Query limits
export GRAPH_GRAPHQL_MAX_COMPLEXITY=100000000
export GRAPH_GRAPHQL_MAX_FIRST=1000

# Disable features you don't need
export DISABLE_BLOCK_INGESTOR=false  # Set true on query-only nodes
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/quickstart">
    Get Graph Node running quickly with Docker
  </Card>

  <Card title="Configuration" icon="sliders" href="/running/configuration">
    Advanced TOML configuration for production
  </Card>

  <Card title="Deploy a Subgraph" icon="upload" href="https://thegraph.com/docs/en/developing/creating-a-subgraph/">
    Learn how to create and deploy subgraphs
  </Card>

  <Card title="Environment Variables" icon="gear" href="/running/environment-variables">
    Complete environment variable reference
  </Card>
</CardGroup>
