A CLI tool that spins up a local Blockscout instance via Docker Compose, scoped to a specific block range — no syncing the whole chain.
| Dependency | Version |
|---|---|
| Node.js | ≥ 18 |
| Docker | ≥ 24 |
| Docker Compose plugin | v2 (docker compose) |
The CLI uses only Node.js built-in modules — no
npm installrequired.
cd /path/to/mock-explorer
npm linkThis symlinks mockexplorer into your global $PATH and points it at this directory. The docker-compose.yml is read from the same package root, then copied to ~/.mockexplorer/ on first use.
npm install -g mockexplorer# Make the script executable (already done if you cloned the repo)
chmod +x /path/to/mock-explorer/bin/mockexplorer.js
# Add a shell alias or symlink
ln -s /path/to/mock-explorer/bin/mockexplorer.js /usr/local/bin/mockexplorerVerify:
mockexplorer --helpOn every start, the CLI:
- Creates
~/.mockexplorer/if it does not exist. - Copies
docker-compose.ymlthere (once). - Writes
~/.mockexplorer/.envwith your RPC URL and block range. - Runs
docker compose up -dfrom that directory.
All Docker Compose commands use --project-directory ~/.mockexplorer/ and --project-name mockexplorer, so the project is always found regardless of your current working directory.
mockexplorer start \
--rpc=<URL> \ # JSON-RPC HTTP endpoint (required)
--start=<BLOCK> \ # First block to index (required)
--end=<BLOCK> \ # Last block to index (required)
[--rpc-headers=<JSON>] # Extra HTTP headers (optional)
Generates ~/.mockexplorer/.env with:
| Variable | Value |
|---|---|
ETHEREUM_JSONRPC_HTTP_URL |
--rpc value |
ETHEREUM_JSONRPC_TRACE_URL |
--rpc value |
FIRST_BLOCK |
--start |
LAST_BLOCK |
--end |
BLOCK_RANGES |
<start>..<end> |
DISABLE_REALTIME_INDEXER |
true |
INDEXER_DISABLE_PENDING_TRANSACTIONS_FETCHER |
true |
ETHEREUM_JSONRPC_HTTP_HEADERS |
--rpc-headers JSON (if provided) |
SECRET_KEY_BASE |
Random 128-char hex (preserved across restarts) |
Then starts the stack with docker compose up -d.
Examples:
# Local Hardhat / Anvil node
mockexplorer start --rpc=http://localhost:8545 --start=0 --end=500
# Mainnet via Infura (restricted range)
mockexplorer start \
--rpc=https://mainnet.infura.io/v3/YOUR_KEY \
--start=18000000 \
--end=18001000
# Authenticated RPC
mockexplorer start \
--rpc=https://private-node.example.com \
--start=1000000 --end=1001000 \
--rpc-headers='{"Authorization":"Bearer YOUR_TOKEN"}'mockexplorer status
Displays the highest indexed block compared to the configured target.
- Queries
http://localhost:4000/api/v2/main-page/blocks(Blockscout REST API). - Falls back to
docker exec→ Postgres query if the API is not yet up.
Sample output:
Configured range
Start block : 18,000,000
End block : 18,001,000
Total blocks: 1,001
→ Querying indexing progress...
ℹ Source: Blockscout API (localhost:4000)
Currently indexed up to block 18,000,742 / Target: 18,001,000
Progress : [████████████████████░░░░░░░░░░░░] 74.2%
Remaining: 258 blocks
mockexplorer stop [--wipe]
| Flag | Effect |
|---|---|
| (none) | docker compose down — stops containers, preserves data volumes |
--wipe |
docker compose down --volumes — stops containers and deletes all data |
Use --wipe when you want a completely fresh sync next time.
mockexplorer extend --end=<NEW_END_BLOCK>
- Reads the current
FIRST_BLOCKfrom~/.mockexplorer/.env. - Updates
LAST_BLOCKandBLOCK_RANGESto the new end block. - Recreates the backend container (
docker compose up -d --force-recreate --no-deps backend) so the Elixir catchup indexer picks up the new ceiling and resumes from the last indexed block — no duplicate work.
# Currently indexed 18 000 000 – 18 001 000; extend to 18 002 000
mockexplorer extend --end=18002000| Service | Port | Description |
|---|---|---|
mockexplorer-frontend |
3000 |
Blockscout Next.js UI |
mockexplorer-backend |
4000 |
Elixir indexer + REST/GraphQL API |
mockexplorer-db |
(internal) | PostgreSQL 15 |
mockexplorer-redis |
(internal) | Redis 7 |
mock-explorer/
├── bin/
│ └── mockexplorer.js ← CLI entry point (no external deps)
├── docker-compose.yml ← Compose definition (copied to ~/.mockexplorer on first run)
├── package.json
└── README.md
~/.mockexplorer/ ← Runtime directory (created automatically)
├── docker-compose.yml ← Working copy used by docker compose
└── .env ← Generated on every `start` / `extend`
Backend keeps restarting
Run docker logs mockexplorer-backend to see errors. The most common cause is an unreachable RPC URL — verify it is accessible from inside the container (try curl from host first).
mockexplorer status shows no progress
The backend needs ~60–120 s to run DB migrations before it starts indexing. Watch logs with:
docker logs -f mockexplorer-backendPort conflicts
If 3000 or 4000 are taken, edit ~/.mockexplorer/docker-compose.yml and change the host-side port mapping (left side of :).