Air-gapped Blockscout deploy + dedicated Archive-RPC node#8
Draft
owenwahlgren wants to merge 4 commits into
Draft
Air-gapped Blockscout deploy + dedicated Archive-RPC node#8owenwahlgren wants to merge 4 commits into
owenwahlgren wants to merge 4 commits into
Conversation
Bundles the Blockscout backend, frontend, postgres, and redis OCI images
into a single archive at blockscout/images.tar.gz on a build machine, then
extracts and runs the compose stack on the target via podman load. The
local and remote networks now optionally launch a dedicated Archive-RPC
avalanchego node bound to 0.0.0.0 with no pruning, used by Blockscout
while the bombard RPC nodes stay loopback-bound.
- scripts/blockscout-pack-images.sh pulls and saves the images
- make pack-blockscout (in local/ and remote/) wraps the standard tarball
with the OCI archive plus compose + helper scripts
- local/internal/network adds L1ArchiveRPCNodeCount and writes
archive-rpcs.txt; archive node uses a chain config with pruning-enabled
false and debug-tracer API
- remote/03_deploy_l1_config.sh starts an Archive-RPC node on port 9656
on the bootstrap host and writes ARCHIVE_RPC_URL to network.env
- scripts/blockscout-up.sh resolves host.docker.internal to the actual
gateway IP at runtime so Elixir's HTTP client can reach the chain
- blockscout-{up,down}.sh detect podman vs docker and pick the right
compose CLI
Two issues surfaced when validating the remote/ flow on a 3-node cluster
where the operator runs on the same host as the Archive-RPC node:
- `start-l1-archive-rpc.sh` was missing `mkdir -p data/archive-rpc/{db,logs}`,
so the `nohup ... > data/archive-rpc/logs/avalanchego.out` redirect failed
and avalanchego never started.
- `to_internal_url` only rewrote `localhost`/`127.0.0.1` to the host-gateway
alias. When ARCHIVE_RPC_URL contains the operator's own eth0 IP, a
rootless-podman container can't reach that IP directly. Added an
`is_local_ip` helper (uses `ip -4 -o addr` or `ifconfig`) and a final
pass that rewrites any host-bound IP through the same gateway resolver.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an offline-friendly Blockscout deployment path and a dedicated Archive-RPC avalanchego node so Blockscout can index a benchmark L1 without exposing the bombard RPCs.
Two halves:
1. Blockscout packaging (podman-first, docker fallback)
scripts/blockscout-pack-images.shpulls the 4 upstream images (backend, frontend, postgres, redis) forlinux/amd64and saves them intoblockscout/images.tar.gz(~458 MB)make pack-blockscout(inlocal/andremote/) bundles that archive plus compose YAML + helper scripts alongside the existing benchmark payload./blockscout.sh uprunspodman load -ion first call, then starts the compose stack — no registry traffic on the air-gapped machinescripts/_blockscout_runtime.shauto-detects podman vs docker and picks<runtime> composevs the legacy<runtime>-composescripts/blockscout-up.shresolveshost.docker.internalto the actual host-gateway IP at runtime (Elixir's HTTP client bypasses/etc/hosts); also rewrites operator-local IPs so the container reaches the host without going through eth0blockscout/docker-compose.ymlindexer config tuned for subnet-evm (noTRACE_URL, HTTP-polling realtime fetcher,FIRST_BLOCK=0,INDEXER_BLOCK_RANGES)2. Dedicated Archive-RPC avalanchego node
L1ArchiveRPCNodeCountconfig (l1ArchiveRpcsJSON field) launches a node bound to0.0.0.0with--http-allowed-hosts=*writeArchiveChainConfigoverlayspruning-enabled: false+debug-tracerAPI onto the shared chain config — applied only to the Archive-RPC node, so bombard's RPCs stay loopback-bound and prunednetwork_data/archive-rpcs.txt(bombard'srpcs.txtexcludes them)remote/03_deploy_l1_config.shruns the equivalent on the bootstrap host (port 9656/9657) and persistsARCHIVE_RPC_URLtonetwork.envremote/blockscout.shprefersARCHIVE_RPC_URLover the bombard RPCTest plan
l1ArchiveRpcs: 1): bombard via loopback rejects foreign Host headers, Blockscout via Archive-RPC indexes successfully (572 blocks / 15,794 txs / 1,803 addresses, 0 missing-trie-node errors)01..03deploy + Archive-RPC verified,remote/blockscout.sh upindexes (690 blocks streaming) under sustained bombardmkdir -p data/archive-rpc/{db,logs}in the Archive-RPC startup template,is_local_iprewrite into_internal_urlOut of scope / follow-ups
127.0.0.1in compose; external browser access currently requires manualsed. A--public-hostflag inblockscout-up.shwould make this proper.Why draft
Verified on Rocky 9.7 single-node and 3-node multi-node setups. Has not been validated on a true air-gapped RHEL host yet — needs a real customer-environment dry run before merge.