fix(start.sh): translate all user-facing text to English

Entire script was in Chinese. Now English-first throughout:
- startup banner, prompts, success/error messages
- setup_telegram(): English instructions and validation messages
- start(): English next-steps after launch
- stop/restart/clean/update/regenerate-keys/show_help: all English
This commit is contained in:
tinkle-community
2026-03-08 19:20:36 +08:00
parent ff1ca4460d
commit 767d8629a3

192
start.sh
View File

@@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
# ═══════════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════════
# NOFX AI Trading System - Docker Quick Start Script # NOFX AI Trading System - Docker Management Script
# Usage: ./start.sh [command] # Usage: ./start.sh [command]
# ═══════════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════════
@@ -45,10 +45,10 @@ detect_compose_cmd() {
elif command -v docker-compose &> /dev/null; then elif command -v docker-compose &> /dev/null; then
COMPOSE_CMD="docker-compose" COMPOSE_CMD="docker-compose"
else else
print_error "Docker Compose 未安装!请先安装 Docker Compose" print_error "Docker Compose not found. Please install Docker Compose first."
exit 1 exit 1
fi fi
print_info "使用 Docker Compose 命令: $COMPOSE_CMD" print_info "Using Docker Compose: $COMPOSE_CMD"
} }
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
@@ -56,12 +56,12 @@ detect_compose_cmd() {
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
check_docker() { check_docker() {
if ! command -v docker &> /dev/null; then if ! command -v docker &> /dev/null; then
print_error "Docker 未安装!请先安装 Docker: https://docs.docker.com/get-docker/" print_error "Docker not found. Please install Docker: https://docs.docker.com/get-docker/"
exit 1 exit 1
fi fi
detect_compose_cmd detect_compose_cmd
print_success "Docker Docker Compose 已安装" print_success "Docker and Docker Compose are installed"
} }
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
@@ -69,11 +69,11 @@ check_docker() {
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
check_env() { check_env() {
if [ ! -f ".env" ]; then if [ ! -f ".env" ]; then
print_warning ".env 不存在,从模板复制..." print_warning ".env not found, copying from template..."
cp .env.example .env cp .env.example .env
print_info "已创建 .env 文件" print_info ".env file created"
fi fi
print_success "环境变量文件存在" print_success "Environment file exists"
} }
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
@@ -83,15 +83,15 @@ is_env_configured() {
local var_name="$1" local var_name="$1"
local value=$(grep "^${var_name}=" .env 2>/dev/null | cut -d'=' -f2-) local value=$(grep "^${var_name}=" .env 2>/dev/null | cut -d'=' -f2-)
# 去除引号 # Strip quotes
value=$(echo "$value" | tr -d '"'"'") value=$(echo "$value" | tr -d '"'"'")
# 检查是否为空或占位符 # Check empty
if [ -z "$value" ]; then if [ -z "$value" ]; then
return 1 return 1
fi fi
# 检查是否是示例值 # Check placeholder values
case "$value" in case "$value" in
*your-*|*YOUR_*|*change-this*|*CHANGE_THIS*|*example*|*EXAMPLE*) *your-*|*YOUR_*|*change-this*|*CHANGE_THIS*|*example*|*EXAMPLE*)
return 1 return 1
@@ -102,22 +102,19 @@ is_env_configured() {
} }
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
# Helper: Generate and set env var in .env file # Helper: Set env var in .env file
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
set_env_var() { set_env_var() {
local var_name="$1" local var_name="$1"
local var_value="$2" local var_value="$2"
# 如果变量已存在(即使是占位符),替换它
if grep -q "^${var_name}=" .env 2>/dev/null; then if grep -q "^${var_name}=" .env 2>/dev/null; then
# macOS 和 Linux 兼容的 sed
if [[ "$OSTYPE" == "darwin"* ]]; then if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' "s|^${var_name}=.*|${var_name}=${var_value}|" .env sed -i '' "s|^${var_name}=.*|${var_name}=${var_value}|" .env
else else
sed -i "s|^${var_name}=.*|${var_name}=${var_value}|" .env sed -i "s|^${var_name}=.*|${var_name}=${var_value}|" .env
fi fi
else else
# 变量不存在,追加
echo "${var_name}=${var_value}" >> .env echo "${var_name}=${var_value}" >> .env
fi fi
} }
@@ -126,51 +123,46 @@ set_env_var() {
# Validation: Encryption Keys in .env # Validation: Encryption Keys in .env
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
check_encryption() { check_encryption() {
print_info "检查加密密钥配置..." print_info "Checking encryption keys..."
local generated=false local generated=false
# 检查并生成 JWT_SECRET
if ! is_env_configured "JWT_SECRET"; then if ! is_env_configured "JWT_SECRET"; then
print_warning "JWT_SECRET 未配置,正在生成..." print_warning "JWT_SECRET not set, generating..."
local jwt_secret=$(openssl rand -base64 32) local jwt_secret=$(openssl rand -base64 32)
set_env_var "JWT_SECRET" "$jwt_secret" set_env_var "JWT_SECRET" "$jwt_secret"
print_success "JWT_SECRET 已生成" print_success "JWT_SECRET generated"
generated=true generated=true
fi fi
# 检查并生成 DATA_ENCRYPTION_KEY
if ! is_env_configured "DATA_ENCRYPTION_KEY"; then if ! is_env_configured "DATA_ENCRYPTION_KEY"; then
print_warning "DATA_ENCRYPTION_KEY 未配置,正在生成..." print_warning "DATA_ENCRYPTION_KEY not set, generating..."
local data_key=$(openssl rand -base64 32) local data_key=$(openssl rand -base64 32)
set_env_var "DATA_ENCRYPTION_KEY" "$data_key" set_env_var "DATA_ENCRYPTION_KEY" "$data_key"
print_success "DATA_ENCRYPTION_KEY 已生成" print_success "DATA_ENCRYPTION_KEY generated"
generated=true generated=true
fi fi
# 检查并生成 RSA_PRIVATE_KEY
if ! is_env_configured "RSA_PRIVATE_KEY"; then if ! is_env_configured "RSA_PRIVATE_KEY"; then
print_warning "RSA_PRIVATE_KEY 未配置,正在生成..." print_warning "RSA_PRIVATE_KEY not set, generating..."
# 生成 RSA 密钥并转换为单行格式(\n 替换为 \\n
local rsa_key=$(openssl genrsa 2048 2>/dev/null | awk '{printf "%s\\n", $0}') local rsa_key=$(openssl genrsa 2048 2>/dev/null | awk '{printf "%s\\n", $0}')
set_env_var "RSA_PRIVATE_KEY" "\"$rsa_key\"" set_env_var "RSA_PRIVATE_KEY" "\"$rsa_key\""
print_success "RSA_PRIVATE_KEY 已生成" print_success "RSA_PRIVATE_KEY generated"
generated=true generated=true
fi fi
if [ "$generated" = true ]; then if [ "$generated" = true ]; then
echo "" echo ""
print_success "所有缺失的密钥已自动生成并保存到 .env" print_success "Missing keys generated and saved to .env"
print_warning "请妥善保管 .env 文件,不要提交到版本控制系统" print_warning "Keep .env safe — do not commit it to version control"
echo "" echo ""
fi fi
print_success "加密密钥检查完成" print_success "Encryption keys OK"
print_info " • JWT_SECRET: OK" print_info " • JWT_SECRET: OK"
print_info " • DATA_ENCRYPTION_KEY: OK" print_info " • DATA_ENCRYPTION_KEY: OK"
print_info " • RSA_PRIVATE_KEY: OK" print_info " • RSA_PRIVATE_KEY: OK"
# 修复 .env 文件权限
chmod 600 .env 2>/dev/null || true chmod 600 .env 2>/dev/null || true
} }
@@ -197,13 +189,12 @@ read_env_vars() {
# Validation: Database Directory (data/) # Validation: Database Directory (data/)
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
check_database() { check_database() {
# Ensure data directory exists
if [ ! -d "data" ]; then if [ ! -d "data" ]; then
print_warning "数据目录不存在,创建 data/ 目录..." print_warning "Data directory missing, creating data/..."
install -m 700 -d data install -m 700 -d data
print_success "已创建 data/ 目录" print_success "data/ directory created"
else else
print_success "数据目录存在" print_success "Data directory exists"
fi fi
} }
@@ -213,39 +204,39 @@ check_database() {
setup_telegram() { setup_telegram() {
if is_env_configured "TELEGRAM_BOT_TOKEN"; then if is_env_configured "TELEGRAM_BOT_TOKEN"; then
local token=$(grep "^TELEGRAM_BOT_TOKEN=" .env | cut -d'=' -f2- | tr -d '"'"'") local token=$(grep "^TELEGRAM_BOT_TOKEN=" .env | cut -d'=' -f2- | tr -d '"'"'")
print_success "Telegram Bot Token 已配置: ${token:0:10}..." print_success "Telegram Bot Token configured: ${token:0:10}..."
return return
fi fi
echo "" echo ""
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${CYAN} 🤖 Telegram Bot 配置(必须)${NC}" echo -e "${CYAN} 🤖 Telegram Bot Setup (required)${NC}"
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo "" echo ""
echo " 还没有 Bot Token按以下步骤获取" echo " Don't have a Bot Token yet? Get one in 60 seconds:"
echo "" echo ""
echo " 1. 打开 Telegram,搜索 @BotFather" echo " 1. Open Telegram, search for @BotFather"
echo " 2. 发送 /newbot" echo " 2. Send /newbot"
echo " 3. 输入机器人名字(随意,如 MyTradingBot" echo " 3. Enter a bot name (e.g. MyTradingBot)"
echo " 4. 输入用户名(必须以 bot 结尾,如 my_trading_bot" echo " 4. Enter a username ending in 'bot' (e.g. my_trading_bot)"
echo " 5. BotFather 会给你一串 Token格式如" echo " 5. BotFather gives you a token like:"
echo " 1234567890:AABBCCDDEEFFaabbccddeeff..." echo " 1234567890:AABBCCDDEEFFaabbccddeeff..."
echo "" echo ""
while true; do while true; do
read -p " 请粘贴 Bot Token: " bot_token read -p " Paste your Bot Token: " bot_token
bot_token=$(echo "$bot_token" | tr -d ' ') bot_token=$(echo "$bot_token" | tr -d ' ')
if [ -z "$bot_token" ]; then if [ -z "$bot_token" ]; then
print_warning "Token 不能为空,请重新输入" print_warning "Token cannot be empty, please try again"
continue continue
fi fi
if [[ ! "$bot_token" =~ ^[0-9]+:.+ ]]; then if [[ ! "$bot_token" =~ ^[0-9]+:.+ ]]; then
print_warning "Token 格式不对(应为 数字:字母, 如 123456:ABC...)请重试" print_warning "Invalid token format (expected digits:letters, e.g. 123456:ABC...) — please retry"
continue continue
fi fi
break break
done done
set_env_var "TELEGRAM_BOT_TOKEN" "$bot_token" set_env_var "TELEGRAM_BOT_TOKEN" "$bot_token"
print_success "Bot Token 已保存 ✅" print_success "Bot Token saved ✅"
echo "" echo ""
} }
@@ -255,7 +246,7 @@ setup_telegram() {
start() { start() {
echo "" echo ""
echo -e "${CYAN}╔══════════════════════════════════════════════════════╗${NC}" echo -e "${CYAN}╔══════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ 🚀 NOFX 个人 AI 交易机器人 启动向导${NC}" echo -e "${CYAN} 🚀 NOFX AI Trading Bot — Startup ${NC}"
echo -e "${CYAN}╚══════════════════════════════════════════════════════╝${NC}" echo -e "${CYAN}╚══════════════════════════════════════════════════════╝${NC}"
echo "" echo ""
@@ -269,7 +260,7 @@ start() {
setup_telegram setup_telegram
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
print_info "正在启动服务..." print_info "Starting services..."
if [ "$1" == "--build" ]; then if [ "$1" == "--build" ]; then
$COMPOSE_CMD up -d --build $COMPOSE_CMD up -d --build
@@ -279,17 +270,17 @@ start() {
echo "" echo ""
echo -e "${GREEN}╔══════════════════════════════════════════════════════╗${NC}" echo -e "${GREEN}╔══════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ ✅ 启动成功!接下来: ${NC}" echo -e "${GREEN}║ ✅ Started! Next steps:${NC}"
echo -e "${GREEN}╚══════════════════════════════════════════════════════╝${NC}" echo -e "${GREEN}╚══════════════════════════════════════════════════════╝${NC}"
echo "" echo ""
echo " 1. 打开 Telegram,找到你的机器人" echo " 1. Open Telegram and find your bot"
echo " 2. 发送 /start 绑定账号" echo " 2. Send /start to bind your account"
echo " 3. 机器人会引导你完成 AI 模型和交易所配置" echo " 3. The bot will guide you through AI model and exchange setup"
echo " 4. 配置完成后,直接发消息让机器人帮你交易" echo " 4. Once configured, just chat to trade"
echo "" echo ""
echo -e " Web 管理界面: ${BLUE}http://localhost:${NOFX_FRONTEND_PORT}${NC}(可选)" echo -e " Web dashboard: ${BLUE}http://localhost:${NOFX_FRONTEND_PORT}${NC} (optional)"
echo -e " 查看日志: ${YELLOW}./start.sh logs${NC}" echo -e " View logs: ${YELLOW}./start.sh logs${NC}"
echo -e " 停止服务: ${YELLOW}./start.sh stop${NC}" echo -e " Stop: ${YELLOW}./start.sh stop${NC}"
echo "" echo ""
} }
@@ -297,18 +288,18 @@ start() {
# Service Management: Stop # Service Management: Stop
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
stop() { stop() {
print_info "正在停止服务..." print_info "Stopping services..."
$COMPOSE_CMD stop $COMPOSE_CMD stop
print_success "服务已停止" print_success "Services stopped"
} }
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
# Service Management: Restart # Service Management: Restart
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
restart() { restart() {
print_info "正在重启服务..." print_info "Restarting services..."
$COMPOSE_CMD restart $COMPOSE_CMD restart
print_success "服务已重启" print_success "Services restarted"
} }
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
@@ -328,25 +319,25 @@ logs() {
status() { status() {
read_env_vars read_env_vars
print_info "服务状态:" print_info "Service status:"
$COMPOSE_CMD ps $COMPOSE_CMD ps
echo "" echo ""
print_info "健康检查:" print_info "Health check:"
curl -s "http://localhost:${NOFX_BACKEND_PORT}/api/health" | jq '.' || echo "后端未响应" curl -s "http://localhost:${NOFX_BACKEND_PORT}/api/health" | jq '.' || echo "Backend not responding"
} }
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
# Maintenance: Clean (Destructive) # Maintenance: Clean (Destructive)
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
clean() { clean() {
print_warning "这将删除所有容器和数据!" print_warning "This will delete all containers and data!"
read -p "确认删除?(yes/no): " confirm read -p "Confirm? (yes/no): " confirm
if [ "$confirm" == "yes" ]; then if [ "$confirm" == "yes" ]; then
print_info "正在清理..." print_info "Cleaning up..."
$COMPOSE_CMD down -v $COMPOSE_CMD down -v
print_success "清理完成" print_success "Cleanup complete"
else else
print_info "已取消" print_info "Cancelled"
fi fi
} }
@@ -354,77 +345,74 @@ clean() {
# Maintenance: Update # Maintenance: Update
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
update() { update() {
print_info "正在更新..." print_info "Updating..."
git pull git pull
$COMPOSE_CMD up -d --build $COMPOSE_CMD up -d --build
print_success "更新完成" print_success "Update complete"
} }
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
# Command: Regenerate all keys (force) # Command: Regenerate all keys (force)
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
regenerate_keys() { regenerate_keys() {
print_warning "这将重新生成所有加密密钥!" print_warning "This will regenerate ALL encryption keys!"
print_warning "如果已有加密数据,重新生成后将无法解密!" print_warning "Any existing encrypted data will become unreadable!"
echo "" echo ""
read -p "确认重新生成?(yes/no): " confirm read -p "Confirm? (yes/no): " confirm
if [ "$confirm" != "yes" ]; then if [ "$confirm" != "yes" ]; then
print_info "已取消" print_info "Cancelled"
return return
fi fi
check_env check_env
print_info "正在生成新的密钥..." print_info "Generating new keys..."
# 生成 JWT_SECRET
local jwt_secret=$(openssl rand -base64 32) local jwt_secret=$(openssl rand -base64 32)
set_env_var "JWT_SECRET" "$jwt_secret" set_env_var "JWT_SECRET" "$jwt_secret"
print_success "JWT_SECRET 已生成" print_success "JWT_SECRET generated"
# 生成 DATA_ENCRYPTION_KEY
local data_key=$(openssl rand -base64 32) local data_key=$(openssl rand -base64 32)
set_env_var "DATA_ENCRYPTION_KEY" "$data_key" set_env_var "DATA_ENCRYPTION_KEY" "$data_key"
print_success "DATA_ENCRYPTION_KEY 已生成" print_success "DATA_ENCRYPTION_KEY generated"
# 生成 RSA_PRIVATE_KEY
local rsa_key=$(openssl genrsa 2048 2>/dev/null | awk '{printf "%s\\n", $0}') local rsa_key=$(openssl genrsa 2048 2>/dev/null | awk '{printf "%s\\n", $0}')
set_env_var "RSA_PRIVATE_KEY" "\"$rsa_key\"" set_env_var "RSA_PRIVATE_KEY" "\"$rsa_key\""
print_success "RSA_PRIVATE_KEY 已生成" print_success "RSA_PRIVATE_KEY generated"
chmod 600 .env 2>/dev/null || true chmod 600 .env 2>/dev/null || true
echo "" echo ""
print_success "所有密钥已重新生成并保存到 .env" print_success "All keys regenerated and saved to .env"
print_warning "请妥善保管 .env 文件" print_warning "Keep .env safe"
} }
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
# Help: Usage Information # Help: Usage Information
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
show_help() { show_help() {
echo "NOFX AI Trading System - Docker 管理脚本" echo "NOFX AI Trading System - Docker Management Script"
echo "" echo ""
echo "用法: ./start.sh [command] [options]" echo "Usage: ./start.sh [command] [options]"
echo "" echo ""
echo "命令:" echo "Commands:"
echo " start [--build] 启动服务(可选:重新构建)" echo " start [--build] Start services (optional: rebuild images)"
echo " stop 停止服务" echo " stop Stop services"
echo " restart 重启服务" echo " restart Restart services"
echo " logs [service] 查看日志(可选:指定服务名 backend/frontend" echo " logs [service] View logs (optional: backend / frontend)"
echo " status 查看服务状态" echo " status Show service status"
echo " clean 清理所有容器和数据" echo " clean Remove all containers and data"
echo " update 更新代码并重启" echo " update Pull latest code and rebuild"
echo " regenerate-keys 重新生成所有加密密钥(慎用)" echo " regenerate-keys Regenerate all encryption keys (destructive)"
echo " help 显示此帮助信息" echo " help Show this help"
echo "" echo ""
echo "示例:" echo "Examples:"
echo " ./start.sh start --build # 构建并启动" echo " ./start.sh start --build # Build and start"
echo " ./start.sh logs backend # 查看后端日志" echo " ./start.sh logs backend # View backend logs"
echo " ./start.sh status # 查看状态" echo " ./start.sh status # Check status"
echo "" echo ""
echo "首次使用:" echo "First time:"
echo " 直接运行 ./start.sh 即可,缺失的密钥会自动生成" echo " Just run ./start.sh — missing keys are generated automatically"
} }
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
@@ -465,7 +453,7 @@ main() {
show_help show_help
;; ;;
*) *)
print_error "未知命令: $1" print_error "Unknown command: $1"
show_help show_help
exit 1 exit 1
;; ;;