# How to Replicate the Docker Network Host Bug
## The Bug
Simulation tests use `--network host` which doesn't work properly on Mac/Windows.
## Prerequisites
- Mac or Windows (bug doesn't affect Linux)
- Docker Desktop installed
- For full test: Node.js v22 and `yarn install` completed
---
## Quick Demo (30 seconds) START HERE
```bash
# Show that Docker container gets wrong network on Mac/Windows
docker run --rm --network host alpine:latest ip addr show | grep "inet "
```
**On Mac/Windows**: You'll see `inet 192.168.65.x/24` (Docker VM network)
**On Linux**: You'll see your actual host network interfaces
This proves `--network host` gives different results on different platforms.
---
## Replicate with Actual Lodestar Test
**Note**: Requires Node.js v22 and dependencies installed. If you can't run this, the Quick Demo above is sufficient to prove the bug.
### Step 1: Set environment variables
```bash
export EL_BINARY_DIR=ethereum/client-go:v1.16.2
export EL_SCRIPT_DIR=gethdocker
export ETH_PORT=8545
export ENGINE_PORT=8551
```
### Step 2: Run the test
```bash
cd packages/beacon-node
yarn test:sim:mergemock
```
### Expected Results
**On Mac/Windows**:
- May fail with connection/timeout errors
- Container uses wrong network (Docker VM instead of host)
- Health checks may fail
**On Linux**:
- Should pass (bug doesn't affect Linux)
---
## Alternative: Manually Verify the Bug
If you can't run the full test, examine the problematic script:
```bash
# Show the problematic line
cat packages/beacon-node/test/scripts/el-interop/gethdocker/post-merge.sh | grep "network host"
```
You'll see:
```bash
docker run --rm ... --network host ...
```
Then compare networks:
```bash
# What container sees with --network host
docker run --rm --network host alpine:latest ip addr show eth0 | grep "inet "
# Your actual Mac network
ifconfig en0 | grep "inet " | head -1
```
The IPs won't match - that's the bug!
---
## Compare with Working Implementation
```bash
cd packages/cli
export GETH_DOCKER_IMAGE=ethereum/client-go:v1.16.2
export LODESTAR_PRESET=minimal
yarn test:sim:multifork
```
**Result**: Works on all platforms (Mac, Windows, Linux)
---
## Files with the Bug
These shell scripts use `--network host`:
```
packages/beacon-node/test/scripts/el-interop/gethdocker/post-merge.sh (line 8)
packages/beacon-node/test/scripts/el-interop/netherminddocker/post-merge.sh (line 16)
packages/beacon-node/test/scripts/el-interop/ethereumjsdocker/post-merge.sh (line 8)
packages/beacon-node/test/scripts/el-interop/mergemock/post-merge.sh (line 9)
```
Search for them:
```bash
grep -r "network host" packages/beacon-node/test/scripts/el-interop/
```
---
## Summary: What You Should See
✅ **Quick Demo** - Container gets `192.168.65.x` (Docker VM), your Mac has different IP
✅ **Problematic Files** - 6 shell scripts use `--network host`
✅ **Alternative Verification** - Manual comparison shows network mismatch
⚠️ **Full Test** - Requires Node.js v22 (optional)
**The bug is**: `--network host` gives containers the Docker VM's network on Mac/Windows, not the actual host network.
**The fix**: Use custom Docker network (already implemented in Crucible framework at `packages/cli/test/utils/crucible/`).
---
## Successfully Replicated? ✅
If you ran the Quick Demo and saw different IPs between the container and your Mac, **you've successfully replicated the bug!** That's all you need to prove it exists.
## ✅ Method 1: Run the Test Locally (Best Verification)
The test itself verifies the fix by checking if:
1. Beacon node can connect to Docker execution client
2. Blocks are produced and exchanged
3. Consensus head matches execution head
### Run This On Your Mac:
```bash
cd /Users/mercynaps/lodestar/packages/beacon-node
# Run the test
EL_BINARY_DIR=g11tech/mergemock:latest \
EL_SCRIPT_DIR=mergemock \
ETH_PORT=8545 \
ENGINE_PORT=8551 \
yarn test:sim:mergemock
```
### What Success Looks Like:
```
✓ Test builder flow (XXXXms)
Done
Test Files 1 passed (1)
Tests 1 passed (1)
```
### What Failure Looks Like (OLD BUG):
```
Error: EL not online in 60 seconds
Error: Health check failed: Connection refused
Error: Failed to connect to execution engine
Timeout: Test exceeded 600000ms
```
**If the test passes, your fix works!** 🎉
The test internally:
- Lines 242-256: Connects to execution engine via RPC
- Lines 244: Fetches latest block from execution client
- Lines 247-256: Verifies consensus and execution heads match
This **only works if communication succeeds**, which proves port forwarding is working correctly.
---
## ✅ Method 2: Manual Communication Test
If you want to manually verify communication, do this:
### Step 1: Start a Docker container with your fix
```bash
cd /Users/mercynaps/lodestar
# Create the custom network (as your fix should do)
docker network create --subnet 192.168.0.0/24 sim-env-net
# Run container with port forwarding (as your fix should do)
docker run -d --name test-geth \
--network sim-env-net \
--ip 192.168.0.2 \
-p 8545:8545 \
-p 8551:8551 \
ethereum/client-go:v1.16.2 \
--http \
--http.addr 0.0.0.0 \
--http.port 8545 \
--http.api "eth,net,engine" \
--authrpc.addr 0.0.0.0 \
--authrpc.port 8551
```
### Step 2: Test communication from host (your Mac)
```bash
# This should return a JSON-RPC response
curl -X POST -H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
http://localhost:8545
# Expected success:
# {"jsonrpc":"2.0","id":1,"result":"0x0"}
# If it fails:
# curl: (7) Failed to connect to localhost port 8545: Connection refused
```
### Step 3: Cleanup
```bash
docker stop test-geth
docker rm test-geth
docker network rm sim-env-net
```
**If the curl succeeds, port forwarding works!**