fix(deploy): 服务器部署修复 — 全栈编译运行通过
在内网服务器 (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 <noreply@anthropic.com>
This commit is contained in:
parent
8e9ee1d38b
commit
0b1de382b0
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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<string>('DB_HOST', 'localhost'),
|
||||
port: config.get<number>('DB_PORT', 5432),
|
||||
username: config.get<string>('DB_USER', 'genex'),
|
||||
password: config.get<string>('DB_PASS', 'genex'),
|
||||
database: config.get<string>('DB_NAME', 'genex_ai'),
|
||||
entities: [AiConversation],
|
||||
synchronize: false,
|
||||
}),
|
||||
}),
|
||||
TypeOrmModule.forFeature([AiConversation]),
|
||||
PassportModule.register({ defaultStrategy: 'jwt' }),
|
||||
JwtModule.registerAsync({
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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)"
|
||||
Loading…
Reference in New Issue