# Base Node Docker Setup: The Two Essential Services Explained

> Master the Base node Docker setup with our guide explaining the essential execution and node services. Learn how they power your Optimism rollup.

- Repository: [Base/node](https://github.com/base/node)
- Tags: deep-dive
- Published: 2026-03-03

---

**The Base node Docker setup consists of two primary services: `execution`, which runs the Ethereum execution client, and `node`, which runs the Optimism rollup node (`op-node`).**

The Base node repository provides a complete Docker composition for running an Optimism-based Layer 2 node. Understanding the two-service architecture is essential for developers deploying Base infrastructure, as each service handles distinct responsibilities within the rollup stack.

## Understanding the Base Node Docker Setup Architecture

The Docker composition implements a **two-layer architecture** that separates the execution client from the rollup node logic. This design follows the Optimism specification, where one service handles Ethereum-compatible block execution while the other manages the derivation of L2 blocks from L1 data.

In [`docker-compose.yml`](https://github.com/base/node/blob/main/docker-compose.yml), these services are defined as `execution` (lines 2-13) and `node` (lines 15-30), with the latter explicitly depending on the former to ensure proper startup order.

## The Execution Service: Running the Ethereum Client

The `execution` service runs the Ethereum execution client—**Geth by default**—which processes L1 blocks and provides JSON-RPC and WebSocket endpoints for blockchain interaction.

### Service Configuration and Build Process

The service builds from a client-specific Dockerfile located at `${CLIENT:-geth}/Dockerfile`, allowing flexibility to switch between execution clients. As defined in the Compose file, the build context passes the `CLIENT` build argument to select the appropriate implementation.

The Dockerfile copies the `execution-entrypoint` script at line 40, which serves as the container's startup command:

```dockerfile

# From geth/Dockerfile

COPY execution-entrypoint /entrypoint.sh

```

### Exposed Ports and Entrypoint

The execution service exposes critical ports for node operation:

- **8545**: JSON-RPC endpoint for standard Ethereum API calls
- **8546**: WebSocket endpoint for real-time subscriptions
- **7301**: Metrics port for monitoring
- **30303**: Peer-to-peer networking port

Verify the execution client is responding with:

```bash
curl -X POST http://localhost:8545 \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'

```

## The Node Service: Operating the Optimism Rollup

The `node` service runs the **Optimism rollup node** (`op-node`), which reads L1 data from the execution client and produces L2 blocks according to the Optimism protocol.

### Dependency on the Execution Layer

As specified in [`docker-compose.yml`](https://github.com/base/node/blob/main/docker-compose.yml) at line 24, the node service declares an explicit dependency on the execution service:

```yaml
depends_on:
  - execution

```

This ensures Docker starts the execution container first, guaranteeing that the L1 RPC endpoints are available before the rollup node attempts to connect.

### Port Configuration and Entrypoint

The node service uses a separate entrypoint script, `op-node-entrypoint`, copied at Dockerfile line 41. This script initializes the rollup node with the appropriate configuration for the selected network (mainnet or Sepolia).

Exposed ports include:

- **7545**: Optimism node JSON-RPC endpoint
- **9222**: P2P port for rollup node networking
- **7300** and **6060**: Metrics and pprof debugging ports

Check the rollup node status with:

```bash
curl -X POST http://localhost:7545 \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'

```

## Starting the Base Node Docker Services

Deploy both services simultaneously using the Docker Compose command from the repository root:

```bash
docker compose up -d execution node

```

This command builds the appropriate client image (defaulting to Geth) and starts both containers in detached mode.

### Switching Execution Clients

Override the default client by setting the `CLIENT` environment variable before running compose:

```bash
CLIENT=reth docker compose up -d execution node

```

Valid options include `geth`, `reth`, `nethermind`, or other supported execution clients, each with their own Dockerfile in the repository.

## Key Files in the Base Node Docker Setup

Understanding these core files helps customize and troubleshoot the two-service architecture:

- **[`docker-compose.yml`](https://github.com/base/node/blob/main/docker-compose.yml)** — Defines the `execution` and `node` services, their build contexts, port mappings, and service dependencies.
- **`geth/Dockerfile`** (or `${CLIENT}/Dockerfile`) — Multi-stage build configuration that compiles both the execution client and `op-node`, copying the respective entrypoint scripts.
- **`execution-entrypoint`** — Shell script that launches the Ethereum execution client with appropriate flags and configuration.
- **`op-node-entrypoint`** — Shell script that initializes and starts the Optimism rollup node, connecting to the execution layer.
- **`.env.mainnet` / `.env.sepolia`** — Environment files providing chain-specific configuration variables passed to both services.

## Summary

The Base node Docker setup implements a clean two-service architecture essential for running an Optimism-based L2 node:

- The **`execution`** service runs the Ethereum client (Geth by default), handling L1 block processing and exposing standard JSON-RPC endpoints on port 8545.
- The **`node`** service runs the `op-node` rollup client, deriving L2 blocks from L1 data and depending on the execution service for connectivity.
- Both services build from client-specific Dockerfiles and communicate through well-defined ports, with the node service explicitly depending on the execution service to ensure proper startup order.

## Frequently Asked Questions

### What are the two main services in the Base node Docker setup?

The two main services are **`execution`** and **`node`**. The execution service runs the Ethereum execution client (such as Geth) that processes L1 blocks and provides RPC endpoints, while the node service runs the Optimism rollup node (`op-node`) that reads L1 data and produces L2 blocks.

### How does the node service depend on the execution service?

The node service declares an explicit dependency in [`docker-compose.yml`](https://github.com/base/node/blob/main/docker-compose.yml) using the `depends_on` directive. This ensures Docker starts the execution container first, guaranteeing that the L1 RPC and WebSocket endpoints are available before the rollup node attempts to connect and synchronize.

### Can I use a different execution client instead of Geth?

Yes, the Base node Docker setup supports multiple execution clients through the `CLIENT` environment variable. You can switch to alternatives like Reth or Nethermind by running `CLIENT=reth docker compose up -d execution node`, which selects the corresponding Dockerfile from the client-specific directory.

### Which ports need to be exposed for the Base node Docker setup to function?

The execution service exposes ports **8545** (JSON-RPC), **8546** (WebSocket), **7301** (metrics), and **30303** (P2P). The node service exposes **7545** (Optimism RPC), **9222** (P2P), and **7300/6060** (metrics/debugging). These ports enable blockchain interaction, peer discovery, and monitoring.