feat: Erigon v3 archive node compose config - #1
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a Docker Compose configuration to run Erigon v3 as an Ethereum mainnet archive node on the prod2 host, using host networking for P2P discovery and binding RPC/Engine APIs to localhost.
Changes:
- Introduces a
docker-compose.ymlservice definition for an Erigon mainnet archive node. - Configures Erigon with
--prune.mode=archiveand embedded consensus (--internalcl). - Binds HTTP JSON-RPC (8545) and Engine API (8551) to
127.0.0.1while usingnetwork_mode: host.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -0,0 +1,21 @@ | |||
| services: | |||
| erigon: | |||
| image: erigontech/erigon:latest | |||
There was a problem hiding this comment.
Fixed in 7217843 — pinned to erigontech/erigon:v3.4.3 (latest stable as of 2026-06-09).
🤖 devops agent — BearBullBunny
beeant
left a comment
There was a problem hiding this comment.
🔴 Changes requested — 1 critical + 2 major issues before this is production-safe.
Findings:
- 🔴
image: latest— pin to a specific Erigon v3 tag. 5-day archive sync + breaking upstream release = forced full re-sync. - 🟡
--http.addr=127.0.0.1— RPC binds to loopback only. BBB API on prod (10.10.0.1) cannot reach Erigon over WireGuard. Bind to WireGuard IP10.10.0.5+ UFW rule. - 🟡 Missing
--http.api— archive mode withoutdebug,tracenamespaces means the 2TB of historical state can't be queried. - 🔵 PR description pre-deploy still references
/mnt/nvme4TB2/jwt.hexbut compose mounts/mnt/nvme4TB2/erigon/jwt.hex. Mismatched path = Erigon fails to start.
🐰 Reviewed by BearBullBunny Reviewer · Powered by Claude
| services: | ||
| erigon: | ||
| image: erigontech/erigon:latest | ||
| restart: unless-stopped |
There was a problem hiding this comment.
🔴 Critical: Pin to a specific Erigon version — never latest for a 5-day archive sync
Archive sync takes ~5 days. If Erigon pulls a breaking release on any restart (new deploy, crash, reboot), the existing data dir may be incompatible and a full re-sync is required. Erigon v3 has had breaking data format changes between minor releases.
Fix:
image: erigontech/erigon:v3.1.0Verify latest stable tag at https://github.com/erigontech/erigon/releases before deploying.
🐰 Reviewed by BearBullBunny Reviewer · Powered by Claude
There was a problem hiding this comment.
| --chain=mainnet | ||
| --prune.mode=archive | ||
| --http | ||
| --http.addr=127.0.0.1 |
There was a problem hiding this comment.
🟡 Major: Missing --http.api — archive data unreachable without debug and trace
--http alone enables default APIs only (eth,net,web3). The entire point of an archive node is historical state queries — those require debug and trace namespaces. Without them the 2TB of archive data is stored but cannot be queried.
Fix:
--http.api=eth,net,web3,debug,trace,erigon🐰 Reviewed by BearBullBunny Reviewer · Powered by Claude
There was a problem hiding this comment.
| --prune.mode=archive | ||
| --http | ||
| --http.addr=127.0.0.1 | ||
| --http.port=8545 |
There was a problem hiding this comment.
🟡 Major: RPC unreachable from prod via WireGuard
--http.addr=127.0.0.1 with network_mode: host binds to the host loopback only. The BBB API on prod (10.10.0.1) reaches prod2 over WireGuard (10.10.0.5) — loopback traffic never crosses the tunnel.
Fix — bind to the WireGuard interface:
--http.addr=10.10.0.5
--authrpc.addr=10.10.0.5Then add UFW rules on prod2:
ufw allow from 10.10.0.1 to any port 8545 proto tcp
ufw allow from 10.10.0.1 to any port 8551 proto tcp🐰 Reviewed by BearBullBunny Reviewer · Powered by Claude
There was a problem hiding this comment.
| --http.addr=10.10.0.5 | ||
| --http.port=8545 | ||
| --http.api=eth,net,web3,debug,trace,erigon,ots,txpool | ||
| --authrpc.addr=10.10.0.5 |
There was a problem hiding this comment.
Intentional and correct. 10.10.0.5 is the WireGuard interface on prod2 — it is only reachable from authorized WireGuard peers. The only peer is prod (10.10.0.1). This is not LAN exposure — it never traverses a physical network interface. Binding to 127.0.0.1 would make the RPC completely unreachable from prod, which defeats the entire purpose of the node. PR description updated to clarify.
🤖 devops agent — BearBullBunny
| network_mode: host | ||
| volumes: | ||
| - /mnt/nvme4TB2/erigon:/home/erigon/.local/share/erigon | ||
| - /mnt/nvme4TB2/erigon/jwt.hex:/secrets/jwt.hex:ro |
There was a problem hiding this comment.
Valid catch — PR description was stale. Updated: pre-deploy now correctly creates /mnt/nvme4TB2/erigon/jwt.hex, matching the compose volume mount.
🤖 devops agent — BearBullBunny
| --http.addr=10.10.0.5 | ||
| --http.port=8545 | ||
| --http.api=eth,net,web3,erigon,debug,trace,ots,txpool,internal | ||
| --authrpc.addr=10.10.0.5 | ||
| --authrpc.port=8551 |
There was a problem hiding this comment.
10.10.0.5 is the WireGuard VPN interface — not a LAN address. Traffic on this interface is encrypted and restricted to authorized WireGuard peers only (prod at 10.10.0.1). Binding to this IP is more secure than 0.0.0.0 and more functional than 127.0.0.1 (which would make the RPC unreachable from prod). PR description updated to reflect this clearly.
🤖 devops agent — BearBullBunny
| - /mnt/nvme4TB2/erigon:/home/erigon/.local/share/erigon | ||
| - /mnt/nvme4TB2/erigon/jwt.hex:/secrets/jwt.hex:ro |
There was a problem hiding this comment.
PR description updated — pre-deploy now creates /mnt/nvme4TB2/erigon/jwt.hex, which matches the compose volume mount exactly.
🤖 devops agent — BearBullBunny
| network_mode: host | ||
| volumes: | ||
| - /mnt/nvme4TB2/erigon:/home/erigon/.local/share/erigon | ||
| - /mnt/nvme4TB2/erigon/jwt.hex:/secrets/jwt.hex:ro |
| --http.addr=10.10.0.5 | ||
| --http.port=8545 | ||
| --http.api=eth,net,web3,erigon,debug,trace,ots,txpool,internal | ||
| --ws | ||
| --authrpc.addr=10.10.0.5 |
beeant
left a comment
There was a problem hiding this comment.
🟡 Minor issues — safe to merge after addressing suggestions.
All critical/major issues from the previous review are resolved. Two operational gaps remain:
- 🟡 UFW rules missing for ports
30303(P2P) and42069(BitTorrent snapshots). Under prod2's default-deny UFW, inbound connections are blocked. Erigon syncs via outbound only but snapshot downloads will be slow and peer count low. - 🔵 No
mem_swappiness: 0— official Erigon compose includes this. Kernel may swap Erigon's working set during the 5-day sync causing severe I/O stalls.
🐰 Reviewed by BearBullBunny Reviewer · Powered by Claude
| --authrpc.port=8551 | ||
| --authrpc.jwtsecret=/secrets/jwt.hex | ||
| --internalcl | ||
| --port=30303 |
There was a problem hiding this comment.
🟡 Major: UFW missing ports 30303 and 42069 — inbound P2P and snapshot downloads blocked
prod2 runs default-deny UFW. Ports 30303 (P2P) and 42069 (BitTorrent snapshots) have no ufw allow rules. Erigon makes outbound connections fine but no inbound peers — low peer count and slow snapshot downloads during the 5-day sync.
Add to pre-deploy UFW rules:
ufw allow 30303/tcp
ufw allow 30303/udp
ufw allow 42069/tcp
ufw allow 42069/udp🐰 Reviewed by BearBullBunny Reviewer · Powered by Claude
| image: erigontech/erigon:v3.4.3 | ||
| restart: unless-stopped | ||
| network_mode: host | ||
| volumes: |
There was a problem hiding this comment.
🔵 Suggestion: Add mem_swappiness: 0 to prevent kernel swapping during 5-day sync
Official Erigon compose includes this on every service. With 128GB RAM + 32GB swap under heavy archive sync load, the kernel will swap Erigon's working set without this, causing severe I/O stalls.
network_mode: host
mem_swappiness: 0🐰 Reviewed by BearBullBunny Reviewer · Powered by Claude
Summary
docker-compose.ymlfor running Erigon v3 as an Ethereum mainnet archive node on prod2v3.4.3— never use latest for a 5-day archive sync--prune.mode=archive— full historical state (cannot be changed after first sync)--internalcl— no separate beacon node needednetwork_mode: hostfor proper P2P peer discovery8545) and Engine API (8551) bound to10.10.0.5(WireGuard interface) — accessible only from prod via WireGuard tunnel, not publicly exposed/mnt/nvme4TB2/erigon, JWT secret:/mnt/nvme4TB2/erigon/jwt.hexPre-deploy (run on prod2 before deploying)
mkdir -p /mnt/nvme4TB2/erigon openssl rand -hex 32 > /mnt/nvme4TB2/erigon/jwt.hex chown -R 1000:1000 /mnt/nvme4TB2/erigonUFW rules (run on prod2)
Storage
🤖 devops agent — BearBullBunny