Expanded solutions (10 new industries) and products (Compliance & Data section) to cover full docs.lux.financial capability surface.
977 lines
29 KiB
YAML
977 lines
29 KiB
YAML
# Lux Universe - Production Mainnet Stack
|
|
# Full 5-node validator network with explorers, indexers, and graph node
|
|
#
|
|
# Usage:
|
|
# docker compose up -d # Start mainnet (5 validators)
|
|
# docker compose --profile testnet up -d # Start testnet configuration
|
|
# docker compose --profile graph up -d # Add subgraph indexing
|
|
# docker compose --profile indexers up -d # Add P/X chain indexers
|
|
# docker compose --profile bridge up -d # Add bridge infrastructure
|
|
# docker compose --profile ui up -d # Add frontend UIs
|
|
# docker compose down # Stop all services
|
|
#
|
|
# Mainnet Ports:
|
|
# 9630: Node 1 HTTP 4010: LUX Explorer
|
|
# 9660: Node 2 HTTP 4011: Zoo Explorer
|
|
# 9670: Node 3 HTTP 4012: Hanzo Explorer
|
|
# 9680: Node 4 HTTP 8000: Graph Node
|
|
# 9690: Node 5 HTTP 5001: IPFS
|
|
# 8085: Pricing API
|
|
#
|
|
# Network: lux-network (172.30.0.0/16)
|
|
|
|
networks:
|
|
lux-network:
|
|
driver: bridge
|
|
ipam:
|
|
config:
|
|
- subnet: 172.30.0.0/16
|
|
|
|
volumes:
|
|
postgres-data:
|
|
ipfs-data:
|
|
graph-data:
|
|
node1-data:
|
|
node2-data:
|
|
node3-data:
|
|
node4-data:
|
|
node5-data:
|
|
bridge-nats-data:
|
|
bridge-consul-data:
|
|
redis-data:
|
|
iam-data:
|
|
vm-plugins:
|
|
|
|
# ==============================================================================
|
|
# INFRASTRUCTURE SERVICES
|
|
# ==============================================================================
|
|
|
|
services:
|
|
# PostgreSQL 15 - Shared database for all services
|
|
postgres:
|
|
image: ghcr.io/hanzoai/sql:0.1.0
|
|
container_name: lux-postgres
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
|
|
volumes:
|
|
- postgres-data:/var/lib/postgresql/data
|
|
- ./docker/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
|
|
ports:
|
|
- "${POSTGRES_PORT:-5432}:5432"
|
|
networks:
|
|
- lux-network
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
|
|
# Redis Cache
|
|
redis:
|
|
image: ghcr.io/hanzoai/kv:0.1.0
|
|
container_name: lux-redis
|
|
restart: unless-stopped
|
|
command: redis-server --appendonly yes --maxmemory 2gb --maxmemory-policy allkeys-lru
|
|
ports:
|
|
- "${REDIS_PORT:-6380}:6379"
|
|
volumes:
|
|
- redis-data:/data
|
|
networks:
|
|
- lux-network
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
|
|
# Pricing API - CoinGecko price cache
|
|
pricing:
|
|
build: ./pricing
|
|
image: ghcr.io/luxfi/pricing:0.1.0
|
|
container_name: lux-pricing
|
|
restart: unless-stopped
|
|
environment:
|
|
- COINGECKO_API_KEY=${COINGECKO_API_KEY:?Set COINGECKO_API_KEY in .env}
|
|
- PORT=8080
|
|
ports:
|
|
- "${PRICING_PORT:-8085}:8080"
|
|
networks:
|
|
- lux-network
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
|
|
# IPFS - Decentralized storage
|
|
ipfs:
|
|
image: ipfs/kubo:latest
|
|
container_name: lux-ipfs
|
|
restart: unless-stopped
|
|
environment:
|
|
IPFS_PROFILE: server
|
|
volumes:
|
|
- ipfs-data:/data/ipfs
|
|
ports:
|
|
- "${IPFS_API_PORT:-5001}:5001"
|
|
- "${IPFS_GATEWAY_PORT:-8080}:8080"
|
|
- "${IPFS_SWARM_PORT:-4001}:4001"
|
|
networks:
|
|
- lux-network
|
|
command: daemon --migrate=true --enable-pubsub-experiment
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "ipfs id || exit 1"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
|
|
# ==============================================================================
|
|
# VM PLUGINS — fetches plugin binaries into shared volume
|
|
# Built by luxfi/chains CI, copied into vm-plugins volume at startup.
|
|
# Nodes mount this volume at /plugins and use --plugin-dir=/plugins.
|
|
# ==============================================================================
|
|
|
|
vm-plugins:
|
|
image: ghcr.io/luxfi/chains/evm:${PLUGIN_VERSION:-latest}
|
|
container_name: lux-vm-plugins
|
|
entrypoint: ["/bin/sh", "-c"]
|
|
command:
|
|
- |
|
|
mkdir -p /plugins
|
|
# Copy EVM plugin (from this image)
|
|
cp /plugin /plugins/evm 2>/dev/null || true
|
|
echo "VM plugins installed"
|
|
# Keep running so dependent services can start
|
|
sleep infinity
|
|
volumes:
|
|
- vm-plugins:/plugins
|
|
networks:
|
|
- lux-network
|
|
|
|
# ==============================================================================
|
|
# LUX VALIDATOR NODES (5 nodes - mainnet minimum)
|
|
# NodeIDs from genesis: ~/work/lux/mainnet/genesis_mainnet.json
|
|
# ==============================================================================
|
|
|
|
# Node 1 - Bootstrap node (NodeID-FrtEjhat6RUqjEWCJgYZKqBaxY2Woyy5G)
|
|
lux-node-1:
|
|
image: ghcr.io/luxfi/node:${NODE_VERSION:-latest}
|
|
container_name: lux-node-1
|
|
restart: unless-stopped
|
|
volumes:
|
|
- node1-data:/app/data
|
|
- ~/.lux/keys/node0:/app/keys:ro
|
|
- ../genesis/configs/mainnet:/app/genesis:ro
|
|
- vm-plugins:/app/plugins:ro
|
|
ports:
|
|
- "${NODE1_HTTP_PORT:-9630}:9630"
|
|
- "${NODE1_STAKING_PORT:-9631}:9631"
|
|
networks:
|
|
lux-network:
|
|
ipv4_address: 172.30.0.10
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
environment:
|
|
NETWORK_ID: ${NETWORK_ID:-1}
|
|
command: >
|
|
--network-id=${NETWORK_ID:-1}
|
|
--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/pchain.json
|
|
--chain-config-dir=/app/configs
|
|
--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/private.key
|
|
--index-enabled
|
|
--api-admin-enabled
|
|
--plugin-dir=/app/plugins
|
|
--data-dir=/app/data
|
|
--log-level=${LOG_LEVEL:-info}
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:9630/ext/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
start_period: 60s
|
|
retries: 3
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
vm-plugins:
|
|
condition: service_started
|
|
|
|
# Node 2 (NodeID-9hq49qGVZN7M7tXxdpF3AqptQGdmPCFnQ)
|
|
lux-node-2:
|
|
image: ghcr.io/luxfi/node:${NODE_VERSION:-latest}
|
|
container_name: lux-node-2
|
|
restart: unless-stopped
|
|
volumes:
|
|
- node2-data:/app/data
|
|
- ~/.lux/keys/node1:/app/keys:ro
|
|
- ../genesis/configs/mainnet:/app/genesis:ro
|
|
- vm-plugins:/app/plugins:ro
|
|
ports:
|
|
- "${NODE2_HTTP_PORT:-9660}:9630"
|
|
- "${NODE2_STAKING_PORT:-9661}:9631"
|
|
networks:
|
|
lux-network:
|
|
ipv4_address: 172.30.0.11
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
environment:
|
|
NETWORK_ID: ${NETWORK_ID:-1}
|
|
command: >
|
|
--network-id=${NETWORK_ID:-1}
|
|
--http-host=0.0.0.0
|
|
--http-port=9630
|
|
--staking-port=9631
|
|
--staking-host=0.0.0.0
|
|
--network-allow-private-ips=true
|
|
--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/private.key
|
|
--bootstrap-ips=172.30.0.10:9631
|
|
--bootstrap-ids=NodeID-FrtEjhat6RUqjEWCJgYZKqBaxY2Woyy5G
|
|
--plugin-dir=/app/plugins
|
|
--data-dir=/app/data
|
|
--log-level=${LOG_LEVEL:-info}
|
|
depends_on:
|
|
- lux-node-1
|
|
- vm-plugins
|
|
|
|
# Node 3 (NodeID-8osEnSC4LQFdG1LMit12CBsE6BfKGHNAw)
|
|
lux-node-3:
|
|
image: ghcr.io/luxfi/node:${NODE_VERSION:-latest}
|
|
container_name: lux-node-3
|
|
restart: unless-stopped
|
|
volumes:
|
|
- node3-data:/app/data
|
|
- ~/.lux/keys/node2:/app/keys:ro
|
|
- ../genesis/configs/mainnet:/app/genesis:ro
|
|
- vm-plugins:/app/plugins:ro
|
|
ports:
|
|
- "${NODE3_HTTP_PORT:-9670}:9630"
|
|
- "${NODE3_STAKING_PORT:-9671}:9631"
|
|
networks:
|
|
lux-network:
|
|
ipv4_address: 172.30.0.12
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
environment:
|
|
NETWORK_ID: ${NETWORK_ID:-1}
|
|
command: >
|
|
--network-id=${NETWORK_ID:-1}
|
|
--http-host=0.0.0.0
|
|
--http-port=9630
|
|
--staking-port=9631
|
|
--staking-host=0.0.0.0
|
|
--network-allow-private-ips=true
|
|
--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/private.key
|
|
--bootstrap-ips=172.30.0.10:9631
|
|
--bootstrap-ids=NodeID-FrtEjhat6RUqjEWCJgYZKqBaxY2Woyy5G
|
|
--plugin-dir=/app/plugins
|
|
--data-dir=/app/data
|
|
--log-level=${LOG_LEVEL:-info}
|
|
depends_on:
|
|
- lux-node-1
|
|
- vm-plugins
|
|
|
|
# Node 4 (NodeID-MrdgTgPuddyo7anomKr4akMcoKzVKcgbG)
|
|
lux-node-4:
|
|
image: ghcr.io/luxfi/node:${NODE_VERSION:-latest}
|
|
container_name: lux-node-4
|
|
restart: unless-stopped
|
|
volumes:
|
|
- node4-data:/app/data
|
|
- ~/.lux/keys/node3:/app/keys:ro
|
|
- ../genesis/configs/mainnet:/app/genesis:ro
|
|
- vm-plugins:/app/plugins:ro
|
|
ports:
|
|
- "${NODE4_HTTP_PORT:-9680}:9630"
|
|
- "${NODE4_STAKING_PORT:-9681}:9631"
|
|
networks:
|
|
lux-network:
|
|
ipv4_address: 172.30.0.13
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
environment:
|
|
NETWORK_ID: ${NETWORK_ID:-1}
|
|
command: >
|
|
--network-id=${NETWORK_ID:-1}
|
|
--http-host=0.0.0.0
|
|
--http-port=9630
|
|
--staking-port=9631
|
|
--staking-host=0.0.0.0
|
|
--network-allow-private-ips=true
|
|
--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/private.key
|
|
--bootstrap-ips=172.30.0.10:9631
|
|
--bootstrap-ids=NodeID-FrtEjhat6RUqjEWCJgYZKqBaxY2Woyy5G
|
|
--plugin-dir=/app/plugins
|
|
--data-dir=/app/data
|
|
--log-level=${LOG_LEVEL:-info}
|
|
depends_on:
|
|
- lux-node-1
|
|
- vm-plugins
|
|
|
|
# Node 5 (NodeID-Mgd5yHs4pe6qRjkBcW5Y7oqHA51j4afcC)
|
|
lux-node-5:
|
|
image: ghcr.io/luxfi/node:${NODE_VERSION:-latest}
|
|
container_name: lux-node-5
|
|
restart: unless-stopped
|
|
volumes:
|
|
- node5-data:/app/data
|
|
- ~/.lux/keys/node4:/app/keys:ro
|
|
- ../genesis/configs/mainnet:/app/genesis:ro
|
|
- vm-plugins:/app/plugins:ro
|
|
ports:
|
|
- "${NODE5_HTTP_PORT:-9690}:9630"
|
|
- "${NODE5_STAKING_PORT:-9691}:9631"
|
|
networks:
|
|
lux-network:
|
|
ipv4_address: 172.30.0.14
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
environment:
|
|
NETWORK_ID: ${NETWORK_ID:-1}
|
|
command: >
|
|
--network-id=${NETWORK_ID:-1}
|
|
--http-host=0.0.0.0
|
|
--http-port=9630
|
|
--staking-port=9631
|
|
--staking-host=0.0.0.0
|
|
--network-allow-private-ips=true
|
|
--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/private.key
|
|
--bootstrap-ips=172.30.0.10:9631
|
|
--bootstrap-ids=NodeID-FrtEjhat6RUqjEWCJgYZKqBaxY2Woyy5G
|
|
--plugin-dir=/app/plugins
|
|
--data-dir=/app/data
|
|
--log-level=${LOG_LEVEL:-info}
|
|
depends_on:
|
|
- lux-node-1
|
|
- vm-plugins
|
|
|
|
# ==============================================================================
|
|
# BLOCKSCOUT EXPLORERS
|
|
# ==============================================================================
|
|
|
|
# LUX C-Chain Explorer (Chain ID: 96369)
|
|
lux-explorer:
|
|
image: ghcr.io/luxfi/explorer:0.1.0
|
|
container_name: lux-explorer
|
|
restart: unless-stopped
|
|
command: sh -c "bin/blockscout eval 'Elixir.Explorer.ReleaseTasks.create_and_migrate()' && bin/blockscout start"
|
|
environment:
|
|
ETHEREUM_JSONRPC_VARIANT: geth
|
|
ETHEREUM_JSONRPC_HTTP_URL: http://lux-node-1:9630/ext/bc/C/rpc
|
|
ETHEREUM_JSONRPC_TRACE_URL: http://lux-node-1:9630/ext/bc/C/rpc
|
|
ETHEREUM_JSONRPC_WS_URL: ws://lux-node-1:9630/ext/bc/C/ws
|
|
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/explorer_lux
|
|
NETWORK: LUX
|
|
SUBNETWORK: C-Chain
|
|
COIN: LUX
|
|
COIN_NAME: LUX
|
|
CHAIN_ID: ${LUX_CHAIN_ID:-96369}
|
|
POOL_SIZE: 50
|
|
ECTO_USE_SSL: "false"
|
|
HEART_BEAT_TIMEOUT: 30
|
|
BLOCKSCOUT_HOST: localhost
|
|
BLOCKSCOUT_PROTOCOL: http
|
|
DISABLE_EXCHANGE_RATES: "true"
|
|
CHECKSUM_FUNCTION: eth
|
|
SECRET_KEY_BASE: ${SECRET_KEY_BASE:-change-me-in-production}
|
|
ports:
|
|
- "${LUX_EXPLORER_PORT:-4010}:4000"
|
|
networks:
|
|
- lux-network
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
lux-node-1:
|
|
condition: service_healthy
|
|
|
|
# Zoo Mainnet Explorer (Chain ID: 200200)
|
|
zoo-explorer:
|
|
image: ghcr.io/luxfi/explorer:0.1.0
|
|
container_name: zoo-explorer
|
|
restart: unless-stopped
|
|
profiles:
|
|
- explorers
|
|
command: sh -c "bin/blockscout eval 'Elixir.Explorer.ReleaseTasks.create_and_migrate()' && bin/blockscout start"
|
|
environment:
|
|
ETHEREUM_JSONRPC_VARIANT: geth
|
|
ETHEREUM_JSONRPC_HTTP_URL: http://lux-node-1:9630/ext/bc/${ZOO_BLOCKCHAIN_ID:-zoo}/rpc
|
|
ETHEREUM_JSONRPC_TRACE_URL: http://lux-node-1:9630/ext/bc/${ZOO_BLOCKCHAIN_ID:-zoo}/rpc
|
|
ETHEREUM_JSONRPC_WS_URL: ws://lux-node-1:9630/ext/bc/${ZOO_BLOCKCHAIN_ID:-zoo}/ws
|
|
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/explorer_zoo
|
|
NETWORK: Zoo
|
|
SUBNETWORK: Zoo Network
|
|
COIN: ZOO
|
|
COIN_NAME: ZOO
|
|
CHAIN_ID: ${ZOO_CHAIN_ID:-200200}
|
|
POOL_SIZE: 50
|
|
ECTO_USE_SSL: "false"
|
|
HEART_BEAT_TIMEOUT: 30
|
|
BLOCKSCOUT_HOST: localhost
|
|
BLOCKSCOUT_PROTOCOL: http
|
|
DISABLE_EXCHANGE_RATES: "true"
|
|
CHECKSUM_FUNCTION: eth
|
|
SECRET_KEY_BASE: ${SECRET_KEY_BASE:-change-me-in-production}
|
|
ports:
|
|
- "${ZOO_EXPLORER_PORT:-4011}:4000"
|
|
networks:
|
|
- lux-network
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
lux-node-1:
|
|
condition: service_healthy
|
|
|
|
# Hanzo AI Chain Explorer (Chain ID: 36963)
|
|
hanzo-explorer:
|
|
image: ghcr.io/luxfi/explorer:0.1.0
|
|
container_name: hanzo-explorer
|
|
restart: unless-stopped
|
|
profiles:
|
|
- explorers
|
|
command: sh -c "bin/blockscout eval 'Elixir.Explorer.ReleaseTasks.create_and_migrate()' && bin/blockscout start"
|
|
environment:
|
|
ETHEREUM_JSONRPC_VARIANT: geth
|
|
ETHEREUM_JSONRPC_HTTP_URL: http://lux-node-1:9630/ext/bc/${HANZO_BLOCKCHAIN_ID:-hanzo}/rpc
|
|
ETHEREUM_JSONRPC_TRACE_URL: http://lux-node-1:9630/ext/bc/${HANZO_BLOCKCHAIN_ID:-hanzo}/rpc
|
|
ETHEREUM_JSONRPC_WS_URL: ws://lux-node-1:9630/ext/bc/${HANZO_BLOCKCHAIN_ID:-hanzo}/ws
|
|
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/explorer_hanzo
|
|
NETWORK: Hanzo
|
|
SUBNETWORK: AI Chain
|
|
COIN: HANZO
|
|
COIN_NAME: HANZO
|
|
CHAIN_ID: ${HANZO_CHAIN_ID:-36963}
|
|
POOL_SIZE: 50
|
|
ECTO_USE_SSL: "false"
|
|
HEART_BEAT_TIMEOUT: 30
|
|
BLOCKSCOUT_HOST: localhost
|
|
BLOCKSCOUT_PROTOCOL: http
|
|
DISABLE_EXCHANGE_RATES: "true"
|
|
CHECKSUM_FUNCTION: eth
|
|
SECRET_KEY_BASE: ${SECRET_KEY_BASE:-change-me-in-production}
|
|
ports:
|
|
- "${HANZO_EXPLORER_PORT:-4012}:4000"
|
|
networks:
|
|
- lux-network
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
lux-node-1:
|
|
condition: service_healthy
|
|
|
|
# ==============================================================================
|
|
# GRAPH-NODE (for subgraphs)
|
|
# ==============================================================================
|
|
|
|
graph-node:
|
|
image: graphprotocol/graph-node:latest
|
|
container_name: lux-graph-node
|
|
restart: unless-stopped
|
|
profiles:
|
|
- graph
|
|
environment:
|
|
postgres_host: postgres
|
|
postgres_port: 5432
|
|
postgres_user: ${POSTGRES_USER:-postgres}
|
|
postgres_pass: ${POSTGRES_PASSWORD:-postgres}
|
|
postgres_db: graph_node
|
|
ipfs: ipfs:5001
|
|
ethereum: "lux:http://lux-node-1:9630/ext/bc/C/rpc"
|
|
GRAPH_LOG: ${GRAPH_LOG:-info}
|
|
GRAPH_ETHEREUM_CLEANUP_BLOCKS: "true"
|
|
ports:
|
|
- "${GRAPH_HTTP_PORT:-8000}:8000"
|
|
- "${GRAPH_WS_PORT:-8001}:8001"
|
|
- "${GRAPH_ADMIN_PORT:-8020}:8020"
|
|
- "${GRAPH_METRICS_PORT:-8040}:8040"
|
|
networks:
|
|
- lux-network
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
ipfs:
|
|
condition: service_healthy
|
|
lux-node-1:
|
|
condition: service_healthy
|
|
|
|
# ==============================================================================
|
|
# CHAIN INDEXERS (P, X chains)
|
|
# ==============================================================================
|
|
|
|
# P-Chain Indexer (Platform - Validators, Staking)
|
|
pchain-indexer:
|
|
build:
|
|
context: ../indexer
|
|
dockerfile: Dockerfile
|
|
container_name: lux-pchain-indexer
|
|
restart: unless-stopped
|
|
profiles:
|
|
- indexers
|
|
command: ["-chain", "pchain", "-port", "4000"]
|
|
environment:
|
|
RPC_ENDPOINT: http://lux-node-1:9630/ext/bc/P
|
|
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/explorer_pchain?sslmode=disable
|
|
HTTP_PORT: 4000
|
|
ports:
|
|
- "${PCHAIN_INDEXER_PORT:-4100}:4000"
|
|
networks:
|
|
- lux-network
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
lux-node-1:
|
|
condition: service_healthy
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:4000/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
|
|
# X-Chain Indexer (Exchange - Assets, UTXOs)
|
|
xchain-indexer:
|
|
build:
|
|
context: ../indexer
|
|
dockerfile: Dockerfile
|
|
container_name: lux-xchain-indexer
|
|
restart: unless-stopped
|
|
profiles:
|
|
- indexers
|
|
command: ["-chain", "xchain", "-port", "4000"]
|
|
environment:
|
|
RPC_ENDPOINT: http://lux-node-1:9630/ext/bc/X
|
|
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/explorer_xchain?sslmode=disable
|
|
HTTP_PORT: 4000
|
|
ports:
|
|
- "${XCHAIN_INDEXER_PORT:-4200}:4000"
|
|
networks:
|
|
- lux-network
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
lux-node-1:
|
|
condition: service_healthy
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:4000/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
|
|
# ==============================================================================
|
|
# BRIDGE SERVICES (optional profile)
|
|
# ==============================================================================
|
|
|
|
# Bridge NATS messaging
|
|
bridge-nats:
|
|
image: nats:2.10-alpine
|
|
container_name: lux-bridge-nats
|
|
restart: unless-stopped
|
|
profiles:
|
|
- bridge
|
|
ports:
|
|
- "${BRIDGE_NATS_PORT:-4223}:4222"
|
|
- "${BRIDGE_NATS_MONITOR:-8223}:8222"
|
|
command: "-js -m 8222 --store_dir /data"
|
|
volumes:
|
|
- bridge-nats-data:/data
|
|
networks:
|
|
- lux-network
|
|
healthcheck:
|
|
test: ["CMD", "nc", "-z", "localhost", "4222"]
|
|
interval: 5s
|
|
timeout: 3s
|
|
retries: 5
|
|
|
|
# Bridge Consul service discovery
|
|
bridge-consul:
|
|
image: hashicorp/consul:1.17
|
|
container_name: lux-bridge-consul
|
|
restart: unless-stopped
|
|
profiles:
|
|
- bridge
|
|
ports:
|
|
- "${BRIDGE_CONSUL_PORT:-8501}:8500"
|
|
command: "agent -server -bootstrap-expect=1 -ui -client=0.0.0.0"
|
|
volumes:
|
|
- bridge-consul-data:/consul/data
|
|
networks:
|
|
- lux-network
|
|
environment:
|
|
CONSUL_BIND_INTERFACE: eth0
|
|
healthcheck:
|
|
test: ["CMD", "consul", "members"]
|
|
interval: 5s
|
|
timeout: 3s
|
|
retries: 5
|
|
|
|
# Bridge KMS (Vault)
|
|
bridge-kms:
|
|
image: hashicorp/vault:1.15
|
|
container_name: lux-bridge-kms
|
|
restart: unless-stopped
|
|
profiles:
|
|
- bridge
|
|
ports:
|
|
- "${BRIDGE_KMS_PORT:-8200}:8200"
|
|
environment:
|
|
VAULT_DEV_ROOT_TOKEN_ID: ${VAULT_DEV_TOKEN:-devroot}
|
|
VAULT_DEV_LISTEN_ADDRESS: 0.0.0.0:8200
|
|
cap_add:
|
|
- IPC_LOCK
|
|
networks:
|
|
- lux-network
|
|
healthcheck:
|
|
test: ["CMD", "vault", "status"]
|
|
interval: 5s
|
|
timeout: 3s
|
|
retries: 5
|
|
|
|
# ==============================================================================
|
|
# FRONTEND UIs (optional profile)
|
|
# ==============================================================================
|
|
|
|
# LUX Explorer Frontend
|
|
lux-frontend:
|
|
image: ghcr.io/luxfi/explore:0.1.0
|
|
container_name: lux-frontend
|
|
restart: unless-stopped
|
|
profiles:
|
|
- ui
|
|
ports:
|
|
- "${LUX_FRONTEND_PORT:-3100}:3000"
|
|
environment:
|
|
NEXT_PUBLIC_NETWORK_NAME: LUX Network
|
|
NEXT_PUBLIC_NETWORK_SHORT_NAME: LUX
|
|
NEXT_PUBLIC_NETWORK_ID: ${NETWORK_ID:-1}
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_NAME: LUX
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL: LUX
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS: 18
|
|
NEXT_PUBLIC_COLOR_THEME_DEFAULT: dark
|
|
NEXT_PUBLIC_API_HOST: localhost:${LUX_EXPLORER_PORT:-4010}
|
|
NEXT_PUBLIC_API_PROTOCOL: http
|
|
NEXT_PUBLIC_API_BASE_PATH: /
|
|
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL: ws
|
|
NEXT_PUBLIC_APP_HOST: localhost:${LUX_FRONTEND_PORT:-3100}
|
|
NEXT_PUBLIC_APP_PROTOCOL: http
|
|
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED: "true"
|
|
networks:
|
|
- lux-network
|
|
depends_on:
|
|
lux-explorer:
|
|
condition: service_started
|
|
|
|
# LUX Exchange UI (DEX)
|
|
lux-exchange:
|
|
image: ghcr.io/luxfi/exchange:0.1.0
|
|
container_name: lux-exchange
|
|
restart: unless-stopped
|
|
profiles:
|
|
- ui
|
|
ports:
|
|
- "${LUX_EXCHANGE_PORT:-3200}:3000"
|
|
environment:
|
|
NODE_ENV: production
|
|
NEXT_PUBLIC_CHAIN_ID: ${LUX_CHAIN_ID:-96369}
|
|
NEXT_PUBLIC_NETWORK_URL: http://lux-node-1:9630/ext/bc/C/rpc
|
|
NEXT_PUBLIC_EXPLORER_URL: http://localhost:${LUX_EXPLORER_PORT:-4010}
|
|
networks:
|
|
- lux-network
|
|
depends_on:
|
|
lux-node-1:
|
|
condition: service_healthy
|
|
|
|
# LXD Gateway (DEX API for AMM + Orderbook)
|
|
lxd-gateway:
|
|
build:
|
|
context: ../dex
|
|
dockerfile: Dockerfile
|
|
image: lxd-gateway:latest
|
|
container_name: lxd-gateway
|
|
restart: unless-stopped
|
|
profiles:
|
|
- ui
|
|
ports:
|
|
- "${LXD_GATEWAY_PORT:-8080}:8080"
|
|
environment:
|
|
LUX_RPC_URL: http://lux-node-1:9630/ext/bc/C/rpc
|
|
ZOO_RPC_URL: http://lux-node-1:9630/ext/bc/Zoo/rpc
|
|
LOG_LEVEL: info
|
|
networks:
|
|
- lux-network
|
|
depends_on:
|
|
lux-node-1:
|
|
condition: service_healthy
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
|
|
# LUX Wallet
|
|
lux-wallet:
|
|
image: ghcr.io/luxfi/wallet:0.1.0
|
|
container_name: lux-wallet
|
|
restart: unless-stopped
|
|
profiles:
|
|
- ui
|
|
ports:
|
|
- "${LUX_WALLET_PORT:-3300}:3000"
|
|
environment:
|
|
NODE_ENV: production
|
|
NEXT_PUBLIC_CHAIN_ID: ${LUX_CHAIN_ID:-96369}
|
|
NEXT_PUBLIC_RPC_URL: http://localhost:${NODE1_HTTP_PORT:-9630}/ext/bc/C/rpc
|
|
NEXT_PUBLIC_EXPLORER_URL: http://localhost:${LUX_EXPLORER_PORT:-4010}
|
|
networks:
|
|
- lux-network
|
|
depends_on:
|
|
lux-node-1:
|
|
condition: service_healthy
|
|
|
|
# LUX Bridge UI
|
|
lux-bridge:
|
|
image: ghcr.io/luxfi/bridge:0.1.0
|
|
container_name: lux-bridge-ui
|
|
restart: unless-stopped
|
|
profiles:
|
|
- ui
|
|
ports:
|
|
- "${LUX_BRIDGE_PORT:-3400}:3000"
|
|
environment:
|
|
NODE_ENV: production
|
|
NEXT_PUBLIC_CHAIN_ID: ${LUX_CHAIN_ID:-96369}
|
|
NEXT_PUBLIC_RPC_URL: http://localhost:${NODE1_HTTP_PORT:-9630}/ext/bc/C/rpc
|
|
networks:
|
|
- lux-network
|
|
depends_on:
|
|
lux-node-1:
|
|
condition: service_healthy
|
|
|
|
# ==============================================================================
|
|
# DEVELOPMENT TOOLS (optional profile)
|
|
# ==============================================================================
|
|
|
|
# Database Admin UI
|
|
adminer:
|
|
image: adminer:latest
|
|
container_name: lux-adminer
|
|
restart: unless-stopped
|
|
profiles:
|
|
- dev
|
|
ports:
|
|
- "${ADMINER_PORT:-8082}:8080"
|
|
networks:
|
|
- lux-network
|
|
environment:
|
|
ADMINER_DEFAULT_SERVER: postgres
|
|
ADMINER_DESIGN: pepa-linha-dark
|
|
|
|
# Redis UI
|
|
redis-commander:
|
|
image: rediscommander/redis-commander:latest
|
|
container_name: lux-redis-commander
|
|
restart: unless-stopped
|
|
profiles:
|
|
- dev
|
|
ports:
|
|
- "${REDIS_COMMANDER_PORT:-8083}:8081"
|
|
networks:
|
|
- lux-network
|
|
environment:
|
|
REDIS_HOSTS: "local:redis:6379"
|
|
|
|
# ==============================================================================
|
|
# IAM SERVICES (uses shared Hanzo IAM)
|
|
# ==============================================================================
|
|
|
|
# Hanzo IAM - Unified Identity & Access Management
|
|
# Provides lux.id login that routes to iam.hanzo.ai backend
|
|
iam:
|
|
image: ghcr.io/hanzoai/iam:0.1.0
|
|
container_name: lux-iam
|
|
restart: unless-stopped
|
|
profiles:
|
|
- iam
|
|
environment:
|
|
# Database (uses shared postgres)
|
|
- DATABASE_URL=postgres://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/iam?sslmode=disable
|
|
|
|
# Redis
|
|
- REDIS_URL=redis://redis:6379
|
|
|
|
# IAM Config
|
|
- CASDOOR_ORIGIN=${CASDOOR_ORIGIN:-https://lux.id}
|
|
- CASDOOR_APP_NAME=lux-iam
|
|
|
|
# Multi-tenant (routes to shared Hanzo IAM)
|
|
- ENABLE_MULTI_TENANT=true
|
|
- ALLOWED_ORIGINS=lux.id,lux.network,wallet.lux.network,bridge.lux.network
|
|
|
|
# Security
|
|
- ENCRYPTION_KEY=${IAM_ENCRYPTION_KEY}
|
|
volumes:
|
|
- ./iam/init_data.json:/app/init_data.json:ro
|
|
- iam-data:/app/data
|
|
ports:
|
|
- "${IAM_PORT:-8001}:8000"
|
|
networks:
|
|
- lux-network
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:8000/api/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 40s
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.lux-id.rule=Host(`lux.id`)"
|
|
- "traefik.http.routers.lux-id.tls=true"
|
|
- "traefik.http.routers.lux-id.middlewares=org-lux"
|
|
- "traefik.http.middlewares.org-lux.headers.customrequestheaders.X-Org-Name=lux"
|
|
|
|
# ==============================================================================
|
|
# LUX BANK (lux.financial) - B2B Stablecoin Infrastructure
|
|
# ==============================================================================
|
|
|
|
# Bank API - Backend services
|
|
bank-api:
|
|
build:
|
|
context: ./bank
|
|
dockerfile: app/api/Dockerfile
|
|
image: ghcr.io/luxfi/bank-api:0.1.0
|
|
container_name: lux-bank-api
|
|
restart: unless-stopped
|
|
profiles:
|
|
- bank
|
|
environment:
|
|
- NODE_ENV=production
|
|
- DATABASE_URL=postgres://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/bank?sslmode=disable
|
|
- REDIS_URL=redis://redis:6379
|
|
- JWT_SECRET=${BANK_JWT_SECRET}
|
|
- CURRENCY_CLOUD_LOGIN_ID=${CURRENCY_CLOUD_LOGIN_ID}
|
|
- CURRENCY_CLOUD_API_KEY=${CURRENCY_CLOUD_API_KEY}
|
|
- SENDGRID_API_KEY=${SENDGRID_API_KEY}
|
|
- AUTH0_DOMAIN=${AUTH0_DOMAIN}
|
|
- AUTH0_CLIENT_ID=${AUTH0_CLIENT_ID}
|
|
- AUTH0_CLIENT_SECRET=${AUTH0_CLIENT_SECRET}
|
|
ports:
|
|
- "${BANK_API_PORT:-4000}:4000"
|
|
networks:
|
|
- lux-network
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:4000/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.bank-api.rule=Host(`api.lux.financial`)"
|
|
- "traefik.http.routers.bank-api.tls=true"
|
|
|
|
# Bank Dashboard - Client portal
|
|
bank-dash:
|
|
build:
|
|
context: ./bank
|
|
dockerfile: app/dash/Dockerfile
|
|
image: ghcr.io/luxfi/bank-dash:0.1.0
|
|
container_name: lux-bank-dash
|
|
restart: unless-stopped
|
|
profiles:
|
|
- bank
|
|
environment:
|
|
- NODE_ENV=production
|
|
- NEXT_PUBLIC_BASE_URL=https://api.lux.financial
|
|
ports:
|
|
- "${BANK_DASH_PORT:-3500}:3000"
|
|
networks:
|
|
- lux-network
|
|
depends_on:
|
|
- bank-api
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.bank-dash.rule=Host(`app.lux.financial`)"
|
|
- "traefik.http.routers.bank-dash.tls=true"
|
|
|
|
# Bank Marketing Site
|
|
bank-site:
|
|
build:
|
|
context: ./bank
|
|
dockerfile: app/site/Dockerfile
|
|
image: ghcr.io/luxfi/bank-site:0.1.0
|
|
container_name: lux-bank-site
|
|
restart: unless-stopped
|
|
profiles:
|
|
- bank
|
|
environment:
|
|
- NODE_ENV=production
|
|
ports:
|
|
- "${BANK_SITE_PORT:-3501}:3000"
|
|
networks:
|
|
- lux-network
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.bank-site.rule=Host(`lux.financial`)"
|
|
- "traefik.http.routers.bank-site.tls=true"
|
|
|
|
# Bank Admin Dashboard
|
|
bank-admin:
|
|
build:
|
|
context: ./bank
|
|
dockerfile: app/admin/Dockerfile
|
|
image: ghcr.io/luxfi/bank-admin:0.1.0
|
|
container_name: lux-bank-admin
|
|
restart: unless-stopped
|
|
profiles:
|
|
- bank
|
|
environment:
|
|
- NODE_ENV=production
|
|
- NEXT_PUBLIC_BASE_URL=https://api.lux.financial
|
|
ports:
|
|
- "${BANK_ADMIN_PORT:-3502}:3000"
|
|
networks:
|
|
- lux-network
|
|
depends_on:
|
|
- bank-api
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.bank-admin.rule=Host(`admin.lux.financial`)"
|
|
- "traefik.http.routers.bank-admin.tls=true"
|
|
|
|
# Bank Documentation Site
|
|
bank-docs:
|
|
build:
|
|
context: ./bank
|
|
dockerfile: app/docs/Dockerfile
|
|
image: ghcr.io/luxfi/bank-docs:0.1.0
|
|
container_name: lux-bank-docs
|
|
restart: unless-stopped
|
|
profiles:
|
|
- bank
|
|
environment:
|
|
- NODE_ENV=production
|
|
ports:
|
|
- "${BANK_DOCS_PORT:-3503}:3000"
|
|
networks:
|
|
- lux-network
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.bank-docs.rule=Host(`docs.lux.financial`)"
|
|
- "traefik.http.routers.bank-docs.tls=true"
|