From 0b1de382b0b8069575fe2ba14baaa580784e91b3 Mon Sep 17 00:00:00 2001 From: hailin Date: Fri, 20 Feb 2026 05:29:33 -0800 Subject: [PATCH] =?UTF-8?q?fix(deploy):=20=E6=9C=8D=E5=8A=A1=E5=99=A8?= =?UTF-8?q?=E9=83=A8=E7=BD=B2=E4=BF=AE=E5=A4=8D=20=E2=80=94=20=E5=85=A8?= =?UTF-8?q?=E6=A0=88=E7=BC=96=E8=AF=91=E8=BF=90=E8=A1=8C=E9=80=9A=E8=BF=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在内网服务器 (192.168.1.222) 首次部署时发现并修复的所有问题, 涉及 backend (12微服务)、blockchain (Cosmos SDK节点)、前端 (admin-web)。 ## Backend 修复 ### docker-compose.yml - DB_PASSWORD: 从硬编码 `genex_dev_password` 改为 `${DB_PASSWORD}` 环境变量插值, 所有13个服务统一从 .env 读取,避免密码不一致导致连接失败 - Kong 镜像: `kong:3.5-alpine` → `kong:3.5`,alpine 版本在 amd64 上缺少依赖 - chain-indexer: 环境变量名 `CHAIN_RPC_URL` → `RPC_URL` (与 Go 代码 getEnv 一致) - chain-indexer: RPC 地址改为 `http://172.17.0.1:8545` (Docker bridge gateway, 跨 docker-compose network 访问 blockchain 节点的 EVM JSON-RPC) - chain-indexer: 补全缺失的 DB_HOST/DB_PORT/DB_USERNAME/DB_PASSWORD/DB_NAME ### ai-service - ai.module.ts: 移除重复的 TypeOrmModule.forRootAsync — 该模块错误地使用了 DB_USER/DB_PASS (默认 'genex'/'genex') 和独立数据库 genex_ai,与 app.module.ts 中已有的 TypeOrmModule.forRoot 冲突,导致密码认证失败 - app.module.ts: 添加 ConfigModule.forRoot({ isGlobal: true }),因为 JwtModule.registerAsync 依赖 ConfigService 注入 ### 依赖补全 - user-service/package.json: 添加 kafkajs ^2.2.4 (Kafka 事件消费) - admin-service/package.json: 添加 kafkajs ^2.2.4 (Kafka 事件消费) ## Blockchain 修复 ### genex-chain/app.go — 修复 chainConfig panic - 问题: NewGenexApp 被调用两次 (tempApp 注册编码 + 实际启动),cosmos/evm 的 SetChainConfig 在第二次调用时 panic: "chainConfig already set" - 原因: 原代码 `if evmChainID == 0 { evmChainID = GenexEVMChainID }` 导致 tempApp 也使用 8888,SetChainConfig 设置后,实际 app 再次设置时触发 panic - 修复: 移除默认值回退,让 tempApp 使用 evmChainID=0 → DefaultEVMChainID(262144), 实际 app 从 app.toml 读取 8888 后可正常覆盖 ### genex-chain/cmd/genexd/cmd/root.go - 移除未使用的 banktypes import (编译错误) ### docker-compose.yml - 添加 `command: ["start", "--chain-id", "genex-testnet-1"]` 到 x-genex-node 默认配置, 否则 InitChain 时 chain-id 为空导致校验失败 ### init-genesis.sh (新增) - 创世初始化脚本: init → 补丁 genesis.json → 创建验证者 → gentx → collect-gentxs - 将所有默认 denom (aatom) 替换为 agnx (GNX, 18 decimals EVM 兼容) - 配置: evm_denom, bond_denom, mint_denom, gov min_deposit, bank denom_metadata - 启用 JSON-RPC (0.0.0.0:8545/8546)、REST API、CORS - 设置 evm-chain-id=8888 ## 部署结果 - 20 个 Docker 容器全部运行 (4 基础设施 + 12 后端 + 1 区块链节点 + 1 前端 + 2 辅助) - 区块链稳定出块 (height 80+),EVM JSON-RPC 正常 - chain-indexer 实时索引区块 (lag=0) Co-Authored-By: Claude Opus 4.6 --- backend/docker-compose.yml | 33 ++++---- backend/services/admin-service/package.json | 3 +- backend/services/ai-service/src/ai.module.ts | 15 ---- backend/services/ai-service/src/app.module.ts | 2 + backend/services/user-service/package.json | 3 +- blockchain/docker-compose.yml | 1 + blockchain/genex-chain/app.go | 7 +- blockchain/genex-chain/cmd/genexd/cmd/root.go | 1 - blockchain/init-genesis.sh | 82 +++++++++++++++++++ 9 files changed, 112 insertions(+), 35 deletions(-) create mode 100644 blockchain/init-genesis.sh diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml index 4e7b4cc..344530e 100644 --- a/backend/docker-compose.yml +++ b/backend/docker-compose.yml @@ -10,7 +10,7 @@ services: container_name: genex-postgres environment: POSTGRES_USER: genex - POSTGRES_PASSWORD: genex_dev_password + POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_DB: genex ports: - "127.0.0.1:45432:5432" @@ -165,7 +165,7 @@ services: # Kong API Gateway (DB-less / Declarative mode) kong: - image: kong:3.5-alpine + image: kong:3.5 container_name: genex-kong environment: KONG_DATABASE: "off" @@ -207,7 +207,7 @@ services: - DB_HOST=postgres - DB_PORT=5432 - DB_USERNAME=genex - - DB_PASSWORD=genex_dev_password + - DB_PASSWORD=${DB_PASSWORD} - DB_NAME=genex - REDIS_HOST=redis - REDIS_PORT=6379 @@ -239,7 +239,7 @@ services: - DB_HOST=postgres - DB_PORT=5432 - DB_USERNAME=genex - - DB_PASSWORD=genex_dev_password + - DB_PASSWORD=${DB_PASSWORD} - DB_NAME=genex - REDIS_HOST=redis - REDIS_PORT=6379 @@ -268,7 +268,7 @@ services: - DB_HOST=postgres - DB_PORT=5432 - DB_USERNAME=genex - - DB_PASSWORD=genex_dev_password + - DB_PASSWORD=${DB_PASSWORD} - DB_NAME=genex - KAFKA_BROKERS=kafka:9092 - JWT_ACCESS_SECRET=dev-access-secret-change-in-production @@ -293,7 +293,7 @@ services: - DB_HOST=postgres - DB_PORT=5432 - DB_USERNAME=genex - - DB_PASSWORD=genex_dev_password + - DB_PASSWORD=${DB_PASSWORD} - DB_NAME=genex - KAFKA_BROKERS=kafka:9092 - JWT_ACCESS_SECRET=dev-access-secret-change-in-production @@ -318,7 +318,7 @@ services: - DB_HOST=postgres - DB_PORT=5432 - DB_USERNAME=genex - - DB_PASSWORD=genex_dev_password + - DB_PASSWORD=${DB_PASSWORD} - DB_NAME=genex - KAFKA_BROKERS=kafka:9092 - REDIS_HOST=redis @@ -347,7 +347,7 @@ services: - DB_HOST=postgres - DB_PORT=5432 - DB_USERNAME=genex - - DB_PASSWORD=genex_dev_password + - DB_PASSWORD=${DB_PASSWORD} - DB_NAME=genex - REDIS_HOST=redis - REDIS_PORT=6379 @@ -381,7 +381,7 @@ services: - DB_HOST=postgres - DB_PORT=5432 - DB_USERNAME=genex - - DB_PASSWORD=genex_dev_password + - DB_PASSWORD=${DB_PASSWORD} - DB_NAME=genex - MINIO_ENDPOINT=minio - MINIO_PORT=9000 @@ -413,7 +413,7 @@ services: - DB_HOST=postgres - DB_PORT=5432 - DB_USERNAME=genex - - DB_PASSWORD=genex_dev_password + - DB_PASSWORD=${DB_PASSWORD} - DB_NAME=genex - REDIS_HOST=redis - REDIS_PORT=6379 @@ -441,7 +441,7 @@ services: - DB_HOST=postgres - DB_PORT=5432 - DB_USERNAME=genex - - DB_PASSWORD=genex_dev_password + - DB_PASSWORD=${DB_PASSWORD} - DB_NAME=genex - REDIS_HOST=redis - REDIS_PORT=6379 @@ -464,7 +464,12 @@ services: environment: - PORT=3009 - KAFKA_BROKERS=kafka:9092 - - CHAIN_RPC_URL=http://localhost:26657 + - RPC_URL=http://172.17.0.1:8545 + - DB_HOST=postgres + - DB_PORT=5432 + - DB_USERNAME=genex + - DB_PASSWORD=${DB_PASSWORD} + - DB_NAME=genex depends_on: kafka: condition: service_healthy @@ -489,7 +494,7 @@ services: - DB_HOST=postgres - DB_PORT=5432 - DB_USERNAME=genex - - DB_PASSWORD=genex_dev_password + - DB_PASSWORD=${DB_PASSWORD} - DB_NAME=genex - REDIS_HOST=redis - REDIS_PORT=6379 @@ -526,7 +531,7 @@ services: - DB_HOST=postgres - DB_PORT=5432 - DB_USERNAME=genex - - DB_PASSWORD=genex_dev_password + - DB_PASSWORD=${DB_PASSWORD} - DB_NAME=genex - KAFKA_BROKERS=kafka:9092 - REDIS_HOST=redis diff --git a/backend/services/admin-service/package.json b/backend/services/admin-service/package.json index b6020d3..02ba2a4 100644 --- a/backend/services/admin-service/package.json +++ b/backend/services/admin-service/package.json @@ -29,7 +29,8 @@ "bplist-parser": "^0.3.2", "minio": "^8.0.0", "reflect-metadata": "^0.2.1", - "rxjs": "^7.8.1" + "rxjs": "^7.8.1", + "kafkajs": "^2.2.4" }, "devDependencies": { "@nestjs/cli": "^10.3.0", diff --git a/backend/services/ai-service/src/ai.module.ts b/backend/services/ai-service/src/ai.module.ts index 6a0ad5e..366a068 100644 --- a/backend/services/ai-service/src/ai.module.ts +++ b/backend/services/ai-service/src/ai.module.ts @@ -30,21 +30,6 @@ import { AdminAgentController } from './interface/http/controllers/admin-agent.c @Module({ imports: [ - ConfigModule.forRoot({ isGlobal: true }), - TypeOrmModule.forRootAsync({ - imports: [ConfigModule], - inject: [ConfigService], - useFactory: (config: ConfigService) => ({ - type: 'postgres' as const, - host: config.get('DB_HOST', 'localhost'), - port: config.get('DB_PORT', 5432), - username: config.get('DB_USER', 'genex'), - password: config.get('DB_PASS', 'genex'), - database: config.get('DB_NAME', 'genex_ai'), - entities: [AiConversation], - synchronize: false, - }), - }), TypeOrmModule.forFeature([AiConversation]), PassportModule.register({ defaultStrategy: 'jwt' }), JwtModule.registerAsync({ diff --git a/backend/services/ai-service/src/app.module.ts b/backend/services/ai-service/src/app.module.ts index b69c1b4..ba2e2a4 100644 --- a/backend/services/ai-service/src/app.module.ts +++ b/backend/services/ai-service/src/app.module.ts @@ -1,10 +1,12 @@ import { Module } from '@nestjs/common'; +import { ConfigModule } from '@nestjs/config'; import { TypeOrmModule } from '@nestjs/typeorm'; import { ThrottlerModule } from '@nestjs/throttler'; import { AiModule } from './ai.module'; @Module({ imports: [ + ConfigModule.forRoot({ isGlobal: true }), TypeOrmModule.forRoot({ type: 'postgres', host: process.env.DB_HOST || 'localhost', diff --git a/backend/services/user-service/package.json b/backend/services/user-service/package.json index 43315ad..9acb1fc 100644 --- a/backend/services/user-service/package.json +++ b/backend/services/user-service/package.json @@ -28,7 +28,8 @@ "pg": "^8.11.3", "reflect-metadata": "^0.2.1", "rxjs": "^7.8.1", - "typeorm": "^0.3.19" + "typeorm": "^0.3.19", + "kafkajs": "^2.2.4" }, "devDependencies": { "@nestjs/cli": "^10.3.0", diff --git a/blockchain/docker-compose.yml b/blockchain/docker-compose.yml index 1181387..803e8a0 100644 --- a/blockchain/docker-compose.yml +++ b/blockchain/docker-compose.yml @@ -36,6 +36,7 @@ x-genex-node: &genex-node-defaults build: context: ./genex-chain dockerfile: Dockerfile + command: ["start", "--chain-id", "genex-testnet-1"] restart: unless-stopped networks: - genex-net diff --git a/blockchain/genex-chain/app.go b/blockchain/genex-chain/app.go index 7d70532..4df8eb6 100644 --- a/blockchain/genex-chain/app.go +++ b/blockchain/genex-chain/app.go @@ -248,9 +248,10 @@ func NewGenexApp( baseAppOptions ...func(*baseapp.BaseApp), ) *GenexApp { evmChainID := cast.ToUint64(appOpts.Get(srvflags.EVMChainID)) - if evmChainID == 0 { - evmChainID = GenexEVMChainID - } + // Note: don't default to GenexEVMChainID here. + // The real app gets 8888 from app.toml (set by evmconfig.InitAppConfig in root.go). + // tempApp (EmptyAppOptions) uses 0 → DefaultEVMChainID (262144), allowing + // the real app to later override the chain config via SetChainConfig. encodingConfig := evmencoding.MakeConfig(evmChainID) appCodec := encodingConfig.Codec diff --git a/blockchain/genex-chain/cmd/genexd/cmd/root.go b/blockchain/genex-chain/cmd/genexd/cmd/root.go index dbb87e0..f8a3583 100644 --- a/blockchain/genex-chain/cmd/genexd/cmd/root.go +++ b/blockchain/genex-chain/cmd/genexd/cmd/root.go @@ -8,7 +8,6 @@ import ( "github.com/cosmos/evm/x/vm/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/spf13/cast" "github.com/spf13/cobra" "github.com/spf13/viper" diff --git a/blockchain/init-genesis.sh b/blockchain/init-genesis.sh new file mode 100644 index 0000000..8ee5cc8 --- /dev/null +++ b/blockchain/init-genesis.sh @@ -0,0 +1,82 @@ +#!/bin/bash +set -e +CHAIN_ID="genex-testnet-1" +DENOM="agnx" +HOME_DIR="/home/genex/.genexd" +KEYRING="test" +GENESIS="$HOME_DIR/config/genesis.json" + +echo "[1/6] Initializing chain..." +genexd init "genex-us-east-1" --chain-id "$CHAIN_ID" --home "$HOME_DIR" + +echo "[2/6] Patching genesis for Genex denom (agnx)..." +# Replace default denoms with agnx +cat "$GENESIS" | jq ' + # EVM module: set denom to agnx + .app_state.evm.params.evm_denom = "agnx" | + .app_state.evm.params.extended_denom_options.extended_denom = "agnx" | + # Staking: bond denom + .app_state.staking.params.bond_denom = "agnx" | + # Mint: mint denom + .app_state.mint.params.mint_denom = "agnx" | + # Gov: min deposit denom + .app_state.gov.params.min_deposit[0].denom = "agnx" | + .app_state.gov.params.expedited_min_deposit[0].denom = "agnx" | + # Bank: add denom metadata for agnx (18 decimals for EVM compat) + .app_state.bank.denom_metadata = [{ + "description": "The native staking and gas token of Genex Chain", + "denom_units": [ + {"denom": "agnx", "exponent": 0, "aliases": ["attoGNX"]}, + {"denom": "GNX", "exponent": 18, "aliases": []} + ], + "base": "agnx", + "display": "GNX", + "name": "Genex Token", + "symbol": "GNX" + }] | + # FeeMarket: use zero gas for dev + .app_state.feemarket.params.min_gas_price = "0.000000000000000000" | + .app_state.feemarket.params.base_fee = "1000000000.000000000000000000" +' > "${GENESIS}.tmp" && mv "${GENESIS}.tmp" "$GENESIS" + +echo "[3/6] Creating validator key..." +genexd keys add validator --keyring-backend "$KEYRING" --home "$HOME_DIR" 2>&1 + +echo "[4/6] Adding genesis account..." +ADDR=$(genexd keys show validator -a --keyring-backend "$KEYRING" --home "$HOME_DIR") +genexd genesis add-genesis-account "$ADDR" "500000000000000000000000000${DENOM}" --home "$HOME_DIR" --keyring-backend "$KEYRING" + +echo "[5/6] Creating genesis transaction..." +genexd genesis gentx validator "250000000000000000000000000${DENOM}" \ + --chain-id "$CHAIN_ID" \ + --moniker "genex-us-east-1" \ + --commission-rate "0.10" \ + --commission-max-rate "0.20" \ + --commission-max-change-rate "0.01" \ + --min-self-delegation "1" \ + --keyring-backend "$KEYRING" \ + --home "$HOME_DIR" + +echo "[6/6] Collecting genesis transactions and validating..." +genexd genesis collect-gentxs --home "$HOME_DIR" + +# Configure node +sed -i "s/minimum-gas-prices = \"\"/minimum-gas-prices = \"0${DENOM}\"/" "$HOME_DIR/config/app.toml" +# Enable API +sed -i "/\[api\]/,/\[/ s/enable = false/enable = true/" "$HOME_DIR/config/app.toml" +# Enable JSON-RPC +sed -i "/\[json-rpc\]/,/\[/ s/enable = false/enable = true/" "$HOME_DIR/config/app.toml" +sed -i "s/address = \"127.0.0.1:8545\"/address = \"0.0.0.0:8545\"/" "$HOME_DIR/config/app.toml" +sed -i "s/ws-address = \"127.0.0.1:8546\"/ws-address = \"0.0.0.0:8546\"/" "$HOME_DIR/config/app.toml" +# CORS +sed -i "s/cors_allowed_origins = \[\]/cors_allowed_origins = [\"*\"]/" "$HOME_DIR/config/config.toml" +sed -i "s/laddr = \"tcp:\/\/127.0.0.1:26657\"/laddr = \"tcp:\/\/0.0.0.0:26657\"/" "$HOME_DIR/config/config.toml" +# Set EVM chain ID +sed -i "s/evm-chain-id = 262144/evm-chain-id = 8888/" "$HOME_DIR/config/app.toml" 2>/dev/null || true + +echo "" +echo "Genesis initialization complete!" +echo "Chain ID: $CHAIN_ID" +echo "Validator: $ADDR" +echo "EVM Chain ID: 8888" +echo "Denom: $DENOM (GNX, 18 decimals)"