${?DOMAIN} substitution caused rskj to crash with 'Can't read config'.
Hardcoding the host-specific domain for now (rootstock only runs on
de-31). For multi-host deployment later, would need a per-host
templated node.conf or a proxy that rewrites Host header.
rskj's hosts whitelist is exact-match (no wildcards). Use HOCON env-var
substitution ${?DOMAIN} to inject the per-host public domain into the
allowed list. Pass DOMAIN env var into the container via the rskj
template.
Allowed hosts list: [localhost, 127.0.0.1, ::1, ${?DOMAIN}]
- localhost variants for direct/internal access
- DOMAIN for traefik-forwarded requests (Host header = public domain)
Setting hosts via -Dhosts.0=*, -Dhosts.1=*, etc creates an OBJECT in
HOCON (indexed entries), but rskj's schema expects LIST. Result: rskj
warns and falls back to default whitelist (localhost only).
Drop the hosts.X JVM properties entirely. The file /etc/rsk/node.conf
already declares hosts = ["*"] which IS a HOCON LIST. Without the JVM
override, the file value wins.
The rsksmart/rskj:VETIVER-9.0.1 image bakes an env var:
RSKJ_SYS_PROPS=-Drpc.providers.web.http.bind_address=0.0.0.0
-Drpc.providers.web.http.hosts.0=localhost
-Drpc.providers.web.http.hosts.1=127.0.0.1
-Drpc.providers.web.http.hosts.2=::1
These JVM -D system properties take precedence over /etc/rsk/node.conf
in HOCON, so the Host whitelist always resolves to {localhost,127.0.0.1,::1}.
Result: traefik routing to rskj at IP rootstock-mainnet-client:8545
arrives with Host header that doesn't match those three. rskj returns
HTTP 400, traefik translates to 502 Bad Gateway.
Override the env var in the compose template so the http hosts whitelist
contains '*' (any host). Traefik's ipallowlist middleware is the actual
gatekeeper. Affects rootstock-mainnet AND rootstock-bamboo.
VETIVER-9.0.1 enforces rpc.providers.web.http.hosts as a whitelist;
empty list / default rejects everything except 'Host: localhost'.
The traefik route uses 'customrequestheaders.Host=localhost' middleware
to rewrite the Host header, but that middleware appears not to be
applied for the rootstock route - real requests still arrive at rskj
with Host: rpc-de-XX.stakesquid.eu and rskj returns 400 Bad Request,
which traefik translates to 502 Bad Gateway.
Wildcard whitelist is fine here because traefik (with ipallowlist
middleware) is the actual gatekeeper.
Confirmed empirically: 'wget --header=Host:localhost' returns valid
JSON-RPC, anything else returns 400.
VETIVER-9.0.1 silently ignores rpc.modules when configured as a list of
{name,version,enabled} objects. Switch to canonical OBJECT format from
rskj's expected.conf:
modules = { eth { version = "1.0", enabled = "true" } ... }
Without this, the RPC server starts but no modules are registered, so
eth_blockNumber returns method-not-found and show-status flags as 'error'
even though the chain itself imports blocks fine.
Also added 'hosts = []' under rpc.providers.web.http (LIST per
expected.conf, was missing). Same fix applied to bamboo testnet config.
Note: this only resolves mainnet. Bamboo still needs DB recreate due to
unrelated 'Invalid block header size: 22' corruption.
- Service name simplified to rootstock-mainnet (no -client suffix)
- Traefik middlewares handle Host:localhost header rewriting
- Proper WS routing on port 8546
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace nginx proxy with traefik headers middleware for Host rewriting.
Fixes container IP mismatch issues on container restart.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>