Files
universe/compose.testnet.yml
T
zeekayandHanzo Dev 7417193940 A chain answers under one segment, and the fleet asks for it there
luxd moved chain APIs from /v1/bc/<alias> to /v1/chain/<alias> and deleted the
old prefix, and health moved onto typed ops at /v1/health/ops/*. Both landed in
node 1.36.181. Nothing here could move before that image existed, and the image
cannot roll out while the manifests still ask for addresses it no longer serves,
so the pin and the paths move in one commit.

What moved:
  image    1.36.171 -> 1.36.181, digest with it, on devnet/testnet/mainnet
  internal exchange-api, lux-hb2, rpc-tip-gate, the luxd startup script
  probes   /v1/health/liveness -> /v1/health/ops/liveness (bare /v1/health,
           which the local compose healthcheck used, no longer routes at all)
  public   the devnet and testnet gateway routes

Comments that RECORD an observation keep their original spelling: a note saying
/v1/bc/zoo/rpc returned 404 on a given date is a fact about that date, and
rewriting it would make the record false. Only live addresses moved.

1.36.181 also carries chains v1.7.38, so the deployed node has the zkvm
content-derived transaction identity.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-30 16:17:20 -07:00

335 lines
9.5 KiB
YAML

# Lux Universe - Testnet Stack
# Full 5-node validator network for testing
#
# Usage:
# docker compose -f compose.testnet.yml up -d
# docker compose -f compose.testnet.yml --profile explorers up -d
# docker compose -f compose.testnet.yml down
#
# Ports:
# 9740-9748: Node HTTP/Staking (5 validators)
# 4020-4023: Block Explorers (LUX, Zoo, Hanzo, SPC)
# 8081: LXD Gateway
#
# Networks:
# LUX: Chain 96368 (C-Chain testnet)
# Zoo: Chain 200201
# Hanzo: Chain 36962
# SPC: Chain 36910
#
# C-Chain Testnet: 219 blocks | Zoo Testnet: 85 blocks
networks:
testnet:
driver: bridge
ipam:
config:
- subnet: 172.31.0.0/24
volumes:
testnet-postgres:
testnet-redis:
testnet-node1-data:
testnet-node2-data:
testnet-node3-data:
testnet-node4-data:
testnet-node5-data:
x-node-common: &node-common
image: ghcr.io/luxfi/node:${NODE_VERSION:-latest}
restart: unless-stopped
networks:
- testnet
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
NETWORK_ID: 2
services:
# Infrastructure
testnet-postgres:
image: ghcr.io/hanzoai/sql:0.1.0
container_name: testnet-postgres
restart: unless-stopped
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: testnet
volumes:
- testnet-postgres:/var/lib/postgresql/data
ports:
- "15433:5432"
networks:
- testnet
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
testnet-redis:
image: ghcr.io/hanzoai/kv:0.1.0
container_name: testnet-redis
restart: unless-stopped
command: redis-server --appendonly yes
volumes:
- testnet-redis:/data
ports:
- "16380:6379"
networks:
- testnet
# Bootstrap Node (Node 1)
testnet-node-1:
<<: *node-common
container_name: testnet-node-1
volumes:
- testnet-node1-data:/app/data
- ~/.lux/keys/node1:/app/keys:ro
- ../genesis/configs/testnet:/app/genesis:ro
- ../state/rlp/lux-testnet:/app/rlp:ro
ports:
- "9740:9630"
- "9741:9631"
command: >
--network-id=2
--http-host=0.0.0.0
--http-port=9630
--staking-port=9631
--staking-host=0.0.0.0
--network-allow-private-ips=true
--genesis-file=/app/genesis/genesis.json
--staking-tls-cert-file=/app/keys/staking/staker.crt
--staking-tls-key-file=/app/keys/staking/staker.key
--staking-signer-key-file=/app/keys/bls/signer.key
--index-enabled
--api-admin-enabled
--data-dir=/app/data
--log-level=info
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9630/v1/health"]
interval: 30s
timeout: 10s
start_period: 60s
retries: 3
testnet-node-2:
<<: *node-common
container_name: testnet-node-2
volumes:
- testnet-node2-data:/app/data
- ~/.lux/keys/node2:/app/keys:ro
- ../genesis/configs/testnet:/app/genesis:ro
ports:
- "9742:9630"
- "9743:9631"
command: >
--network-id=2
--http-host=0.0.0.0
--http-port=9630
--staking-port=9631
--network-allow-private-ips=true
--genesis-file=/app/genesis/genesis.json
--staking-tls-cert-file=/app/keys/staking/staker.crt
--staking-tls-key-file=/app/keys/staking/staker.key
--staking-signer-key-file=/app/keys/bls/signer.key
--bootstrap-ips=testnet-node-1:9631
--bootstrap-ids=NodeID-FrtEjhat6RUqjEWCJgYZKqBaxY2Woyy5G
--data-dir=/app/data
--log-level=info
depends_on:
testnet-node-1:
condition: service_healthy
testnet-node-3:
<<: *node-common
container_name: testnet-node-3
volumes:
- testnet-node3-data:/app/data
- ~/.lux/keys/node3:/app/keys:ro
- ../genesis/configs/testnet:/app/genesis:ro
ports:
- "9744:9630"
- "9745:9631"
command: >
--network-id=2
--http-host=0.0.0.0
--http-port=9630
--staking-port=9631
--network-allow-private-ips=true
--genesis-file=/app/genesis/genesis.json
--staking-tls-cert-file=/app/keys/staking/staker.crt
--staking-tls-key-file=/app/keys/staking/staker.key
--staking-signer-key-file=/app/keys/bls/signer.key
--bootstrap-ips=testnet-node-1:9631
--bootstrap-ids=NodeID-FrtEjhat6RUqjEWCJgYZKqBaxY2Woyy5G
--data-dir=/app/data
--log-level=info
depends_on:
testnet-node-1:
condition: service_healthy
testnet-node-4:
<<: *node-common
container_name: testnet-node-4
volumes:
- testnet-node4-data:/app/data
- ~/.lux/keys/node4:/app/keys:ro
- ../genesis/configs/testnet:/app/genesis:ro
ports:
- "9746:9630"
- "9747:9631"
command: >
--network-id=2
--http-host=0.0.0.0
--http-port=9630
--staking-port=9631
--network-allow-private-ips=true
--genesis-file=/app/genesis/genesis.json
--staking-tls-cert-file=/app/keys/staking/staker.crt
--staking-tls-key-file=/app/keys/staking/staker.key
--staking-signer-key-file=/app/keys/bls/signer.key
--bootstrap-ips=testnet-node-1:9631
--bootstrap-ids=NodeID-FrtEjhat6RUqjEWCJgYZKqBaxY2Woyy5G
--data-dir=/app/data
--log-level=info
depends_on:
testnet-node-1:
condition: service_healthy
testnet-node-5:
<<: *node-common
container_name: testnet-node-5
volumes:
- testnet-node5-data:/app/data
- ~/.lux/keys/node5:/app/keys:ro
- ../genesis/configs/testnet:/app/genesis:ro
ports:
- "9748:9630"
- "9749:9631"
command: >
--network-id=2
--http-host=0.0.0.0
--http-port=9630
--staking-port=9631
--network-allow-private-ips=true
--genesis-file=/app/genesis/genesis.json
--staking-tls-cert-file=/app/keys/staking/staker.crt
--staking-tls-key-file=/app/keys/staking/staker.key
--staking-signer-key-file=/app/keys/bls/signer.key
--bootstrap-ips=testnet-node-1:9631
--bootstrap-ids=NodeID-FrtEjhat6RUqjEWCJgYZKqBaxY2Woyy5G
--data-dir=/app/data
--log-level=info
depends_on:
testnet-node-1:
condition: service_healthy
# LXD Gateway for DEX
testnet-gateway:
build:
context: ../dex
dockerfile: Dockerfile
image: lxd-gateway:testnet
container_name: testnet-gateway
restart: unless-stopped
ports:
- "8081:8080"
environment:
LUX_RPC_URL: http://testnet-node-1:9630/v1/chain/C/rpc
ZOO_RPC_URL: http://testnet-node-1:9630/v1/chain/zoo/rpc
LOG_LEVEL: info
networks:
- testnet
depends_on:
testnet-node-1:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
# ===========================================================================
# BLOCK EXPLORERS (profile: explorers)
# ===========================================================================
x-explorer-common: &explorer-common
image: ghcr.io/luxfi/explorer:0.1.0
restart: unless-stopped
profiles:
- explorers
command: sh -c "bin/blockscout eval 'Elixir.Explorer.ReleaseTasks.create_and_migrate()' && bin/blockscout start"
networks:
- testnet
depends_on:
testnet-node-1:
condition: service_healthy
testnet-postgres:
condition: service_healthy
testnet-explorer-lux:
<<: *explorer-common
container_name: testnet-explorer-lux
environment:
ETHEREUM_JSONRPC_VARIANT: geth
ETHEREUM_JSONRPC_HTTP_URL: http://testnet-node-1:9630/v1/chain/C/rpc
ETHEREUM_JSONRPC_WS_URL: ws://testnet-node-1:9630/v1/chain/C/ws
DATABASE_URL: postgresql://postgres:postgres@testnet-postgres:5432/explorer_lux
NETWORK: LUX
SUBNETWORK: Testnet
COIN: LUX
CHAIN_ID: 96368
DISABLE_EXCHANGE_RATES: "true"
SECRET_KEY_BASE: ${SECRET_KEY_BASE:-dev-secret-for-testnet}
ports:
- "4020:4000"
testnet-explorer-zoo:
<<: *explorer-common
container_name: testnet-explorer-zoo
environment:
ETHEREUM_JSONRPC_VARIANT: geth
ETHEREUM_JSONRPC_HTTP_URL: http://testnet-node-1:9630/v1/chain/zoo/rpc
DATABASE_URL: postgresql://postgres:postgres@testnet-postgres:5432/explorer_zoo
NETWORK: ZOO
SUBNETWORK: Testnet
COIN: ZOO
CHAIN_ID: 200201
DISABLE_EXCHANGE_RATES: "true"
SECRET_KEY_BASE: ${SECRET_KEY_BASE:-dev-secret-for-testnet}
ports:
- "4021:4000"
testnet-explorer-hanzo:
<<: *explorer-common
container_name: testnet-explorer-hanzo
environment:
ETHEREUM_JSONRPC_VARIANT: geth
ETHEREUM_JSONRPC_HTTP_URL: http://testnet-node-1:9630/v1/chain/hanzo/rpc
DATABASE_URL: postgresql://postgres:postgres@testnet-postgres:5432/explorer_hanzo
NETWORK: HANZO
SUBNETWORK: AI Network Testnet
COIN: AI
CHAIN_ID: 36962
DISABLE_EXCHANGE_RATES: "true"
SECRET_KEY_BASE: ${SECRET_KEY_BASE:-dev-secret-for-testnet}
ports:
- "4022:4000"
testnet-explorer-spc:
<<: *explorer-common
container_name: testnet-explorer-spc
environment:
ETHEREUM_JSONRPC_VARIANT: geth
ETHEREUM_JSONRPC_HTTP_URL: http://testnet-node-1:9630/v1/chain/spc/rpc
DATABASE_URL: postgresql://postgres:postgres@testnet-postgres:5432/explorer_spc
NETWORK: SPC
SUBNETWORK: Sparkle Pony Club Testnet
COIN: SPC
CHAIN_ID: 36910
DISABLE_EXCHANGE_RATES: "true"
SECRET_KEY_BASE: ${SECRET_KEY_BASE:-dev-secret-for-testnet}
ports:
- "4023:4000"