Running a Node
How to run an Ethscriptions AppChain node with Docker Compose
This guide explains how to run your own Ethscriptions AppChain node using Docker Compose.
Prerequisites
Docker Desktop (includes the Compose plugin)
L1 RPC endpoint - Archive-quality recommended for historical sync
Quick Start
# Clone the repository
git clone https://github.com/ethscriptions-protocol/ethscriptions-node.git
cd ethscriptions-node
# Copy the environment template
cp docker-compose/.env.example docker-compose/.env
# Edit .env with your settings (see Environment Reference below)
# At minimum, set L1_RPC_URL to your L1 endpoint
# Bring up the stack
cd docker-compose
docker compose --env-file .env up -d
# Follow logs while it syncs
docker compose logs -f node
# Query the L2 RPC (default port 8545)
curl -X POST http://localhost:8545 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
# Shut down when done
docker compose downServices
The stack runs two containers:
geth
Ethscriptions-customized Ethereum execution client (L2)
node
Ruby derivation app that processes L1 data into L2 blocks
The node waits for geth to be healthy before starting. Both services communicate via a shared IPC socket.
Environment Reference
Key variables in docker-compose/.env:
Core Configuration
COMPOSE_PROJECT_NAME
Docker resource naming prefix
ethscriptions-evm
JWT_SECRET
32-byte hex for Engine API auth (must match geth)
—
L1_NETWORK
Ethereum network (mainnet, sepolia, etc.)
mainnet
L1_RPC_URL
Archive-quality L1 RPC endpoint
—
L1_GENESIS_BLOCK
L1 block where the rollup anchors
17478949
GENESIS_FILE
Genesis snapshot filename
ethscriptions-mainnet.json
GETH_EXTERNAL_PORT
Host port for L2 RPC
8545
Performance Tuning
L1_PREFETCH_FORWARD
Blocks to prefetch ahead
200
L1_PREFETCH_THREADS
Prefetch worker threads
10
JOB_CONCURRENCY
SolidQueue worker concurrency
6
JOB_THREADS
Job worker threads
3
Geth Configuration
GC_MODE
full (pruned) or archive (full history)
full
STATE_HISTORY
State trie history depth
100000
TX_HISTORY
Transaction history depth
100000
ENABLE_PREIMAGES
Retain preimages
true
CACHE_SIZE
State cache size
25000
Validation (Optional)
VALIDATION_ENABLED
Enable validator against reference API
false
ETHSCRIPTIONS_API_BASE_URL
Reference API endpoint
—
ETHSCRIPTIONS_API_KEY
API authentication key
—
Monitoring
View Logs
Check Block Height
Check Sync Status
The derivation node logs show the current L1 block being processed. Compare this to the current L1 head to gauge sync progress.
Validator (Optional)
The validator compares L2 state against a reference Ethscriptions API to verify derivation correctness. It pauses the importer when discrepancies appear so you can investigate.
To enable:
The temporary SQLite databases in storage/ and the SolidQueue worker pool support this reconciliation. Once historical import is verified, the derivation app remains stateless.
Local Development
If you want to modify the Ruby code outside of Docker:
The Docker Compose stack is recommended for production-like runs.
Troubleshooting
Node won't start
Check that geth is healthy:
docker compose psVerify
L1_RPC_URLis accessibleEnsure
JWT_SECRETmatches between services
Slow sync
Increase
L1_PREFETCH_FORWARDandL1_PREFETCH_THREADSUse a faster L1 RPC endpoint
Consider archive mode (
GC_MODE=archive) only if needed
Out of disk space
Pruned mode (
GC_MODE=full) uses less spaceReduce
STATE_HISTORYandTX_HISTORY
Resources
Last updated