Files
pezkuwi-subquery/docker-compose.prod.yml
pezkuwichain 676f2f7474 fix(noter): use the public endpoints and fail loudly when scans stop (#1)
The bot pointed at the block-producing nodes' RPC ports. Those bind to
localhost, so once they stopped being exposed to the internet the bot lost
every chain at once and has submitted nothing since. `staking_score` gates
the entire trust score, so a noter that cannot reach the chains does not
degrade the score — it zeroes it for every tracked account.

Point it at the public endpoints instead, which is what an external client
should use and what the code already defaulted to. They are TLS-terminated
rather than plaintext ws:// across the internet, and this drops a hardcoded
node address from the repository.

Reaching the chains again is not enough on its own: the outage lasted three
weeks because reconnecting forever looks identical to working. The bot now
writes a heartbeat when a scan *completes*, a container healthcheck reads it,
and a watchdog exits once it goes stale so the restart policy turns a silent
stall into a visibly crash-looping container.
2026-08-05 12:45:25 -07:00

199 lines
5.5 KiB
YAML

services:
postgres:
container_name: postgres-pezkuwi
image: postgres:16-alpine
ports:
- 5432:5432
volumes:
- pgdata:/var/lib/postgresql/data
- ./docker/init:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 10
environment:
POSTGRES_PASSWORD: pezkuwi_subquery_2024
restart: always
subquery-node-relay:
container_name: node-pezkuwi-relay
build:
context: .
dockerfile: docker/Dockerfile.node
depends_on:
postgres: { condition: service_healthy }
restart: always
environment:
TZ: UTC
DB_USER: postgres
DB_PASS: pezkuwi_subquery_2024
DB_DATABASE: postgres
DB_HOST: postgres
DB_PORT: 5432
volumes:
- ./:/app/project
command:
- -f=/app/project/pezkuwi.yaml
- --db-schema=subquery-pezkuwi-staking
- --disable-historical=true
- --batch-size=30
subquery-node-assethub:
container_name: node-pezkuwi-assethub
build:
context: .
dockerfile: docker/Dockerfile.node
depends_on:
postgres: { condition: service_healthy }
restart: always
environment:
TZ: UTC
DB_USER: postgres
DB_PASS: pezkuwi_subquery_2024
DB_DATABASE: postgres
DB_HOST: postgres
DB_PORT: 5432
volumes:
- ./:/app/project
command:
- -f=/app/project/pezkuwi-assethub.yaml
- --db-schema=subquery-pezkuwi-assethub
- --disable-historical=true
- --batch-size=30
graphql-engine:
container_name: query-pezkuwi
image: onfinality/subql-query:v1.5.0
ports:
- 3000:3000
depends_on:
- subquery-node-relay
restart: always
environment:
DB_USER: postgres
DB_PASS: pezkuwi_subquery_2024
DB_DATABASE: postgres
DB_HOST: postgres
DB_PORT: 5432
command:
- --name=subquery-pezkuwi-staking
- --playground
- --indexer=http://subquery-node-relay:3000
graphql-engine-assethub:
container_name: query-pezkuwi-ah
image: onfinality/subql-query:v1.5.0
ports:
- 3001:3000
depends_on:
- subquery-node-assethub
restart: always
environment:
DB_USER: postgres
DB_PASS: pezkuwi_subquery_2024
DB_DATABASE: postgres
DB_HOST: postgres
DB_PORT: 5432
command:
- --name=subquery-pezkuwi-assethub
- --playground
- --indexer=http://subquery-node-assethub:3000
subquery-node-governance:
container_name: node-pezkuwi-governance
build:
context: .
dockerfile: docker/Dockerfile.node
depends_on:
postgres: { condition: service_healthy }
restart: always
environment:
TZ: UTC
DB_USER: postgres
DB_PASS: pezkuwi_subquery_2024
DB_DATABASE: postgres
DB_HOST: postgres
DB_PORT: 5432
volumes:
- ./:/app/project
command:
- -f=/app/project/pezkuwi-governance.yaml
- --db-schema=subquery-pezkuwi-governance
- --disable-historical=true
- --batch-size=30
graphql-engine-governance:
container_name: query-pezkuwi-gov
image: onfinality/subql-query:v1.5.0
ports:
- 3002:3000
depends_on:
- subquery-node-governance
restart: always
environment:
DB_USER: postgres
DB_PASS: pezkuwi_subquery_2024
DB_DATABASE: postgres
DB_HOST: postgres
DB_PORT: 5432
command:
- --name=subquery-pezkuwi-governance
- --playground
- --indexer=http://subquery-node-governance:3000
noter-bot:
container_name: noter-pezkuwi
build:
context: ./noter
dockerfile: Dockerfile
depends_on:
postgres: { condition: service_healthy }
restart: unless-stopped
secrets:
- noter_mnemonic
environment:
TZ: UTC
# The block-producing nodes bind their RPC to localhost by design — reaching
# them from here needed the ports open to the internet, and closing them (as
# they should be) silently cut this bot off from every chain. These are the
# public endpoints, which is what an external client is supposed to use, and
# they are TLS-terminated rather than plaintext ws:// across the internet.
RELAY_RPC: wss://rpc.pezkuwichain.io
ASSET_HUB_RPC: wss://asset-hub-rpc.pezkuwichain.io
PEOPLE_RPC: wss://people-rpc.pezkuwichain.io
SCAN_INTERVAL_MS: "300000"
# The bot writes a heartbeat when a scan completes, not when it merely stays
# up: an endless reconnect loop kept the container "Up" for three weeks while
# no staking data reached the People chain.
healthcheck:
test: ["CMD", "node", "-e", "const fs=require('fs');const i=parseInt(process.env.SCAN_INTERVAL_MS||'300000',10);let t=0;try{t=Number(fs.readFileSync(process.env.HEARTBEAT_FILE||'/tmp/noter-heartbeat','utf8'))}catch{};process.exit(Number.isFinite(t)&&Date.now()-t<i*3?0:1)"]
interval: 60s
timeout: 10s
retries: 3
# The first scan has to walk every tracked account before it can report.
start_period: 10m
payout-bot:
container_name: payout-pezkuwi
build:
context: ./payout-bot
dockerfile: Dockerfile
restart: unless-stopped
secrets:
- payout_mnemonic
environment:
TZ: UTC
ASSET_HUB_RPC: wss://asset-hub-rpc.pezkuwichain.io
MNEMONIC_FILE: /run/secrets/payout_mnemonic
INTERVAL_MS: "600000"
secrets:
noter_mnemonic:
file: ./secrets/noter_mnemonic.txt
payout_mnemonic:
file: ./secrets/payout_mnemonic.txt
volumes:
pgdata: