2025-09-08 07:21:48 +08:00
|
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
|
|
|
|
# n8n 中文版快速启动脚本
|
|
|
|
|
|
# 作者: 小齐
|
|
|
|
|
|
# 最后更新: 2025-09-07
|
|
|
|
|
|
|
|
|
|
|
|
set -e
|
|
|
|
|
|
|
|
|
|
|
|
# 颜色定义
|
|
|
|
|
|
RED='\033[0;31m'
|
|
|
|
|
|
GREEN='\033[0;32m'
|
|
|
|
|
|
YELLOW='\033[1;33m'
|
|
|
|
|
|
BLUE='\033[0;34m'
|
|
|
|
|
|
NC='\033[0m' # No Color
|
|
|
|
|
|
|
|
|
|
|
|
# 打印带颜色的信息
|
|
|
|
|
|
print_info() {
|
|
|
|
|
|
echo -e "${BLUE}[信息]${NC} $1"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
print_success() {
|
|
|
|
|
|
echo -e "${GREEN}[成功]${NC} $1"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
print_warning() {
|
|
|
|
|
|
echo -e "${YELLOW}[警告]${NC} $1"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
print_error() {
|
|
|
|
|
|
echo -e "${RED}[错误]${NC} $1"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 显示启动横幅
|
|
|
|
|
|
show_banner() {
|
|
|
|
|
|
echo -e "${BLUE}"
|
|
|
|
|
|
echo "======================================"
|
|
|
|
|
|
echo " n8n 中文版快速启动脚本"
|
|
|
|
|
|
echo " 版本: n8n-1.109.2 with 中文翻译"
|
2025-09-08 08:22:54 +08:00
|
|
|
|
echo " 维护者: xiaoqi"
|
2025-09-08 07:21:48 +08:00
|
|
|
|
echo "======================================"
|
|
|
|
|
|
echo -e "${NC}"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 检查依赖
|
|
|
|
|
|
check_dependencies() {
|
|
|
|
|
|
print_info "正在检查系统依赖..."
|
|
|
|
|
|
|
|
|
|
|
|
# 检查 Node.js
|
|
|
|
|
|
if ! command -v node &> /dev/null; then
|
|
|
|
|
|
print_error "Node.js 未安装或未在 PATH 中"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 检查 pnpm
|
|
|
|
|
|
if ! command -v pnpm &> /dev/null; then
|
|
|
|
|
|
print_error "pnpm 未安装或未在 PATH 中"
|
|
|
|
|
|
print_info "请先安装 pnpm: npm install -g pnpm"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
print_success "依赖检查通过"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 检查端口占用
|
|
|
|
|
|
check_port() {
|
|
|
|
|
|
local port=5678
|
|
|
|
|
|
if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null 2>&1; then
|
|
|
|
|
|
print_warning "端口 $port 已被占用"
|
|
|
|
|
|
print_info "正在查看占用进程..."
|
|
|
|
|
|
lsof -i :$port
|
|
|
|
|
|
|
|
|
|
|
|
read -p "是否杀死占用进程?(y/N): " kill_process
|
|
|
|
|
|
if [[ $kill_process =~ ^[Yy]$ ]]; then
|
|
|
|
|
|
print_info "正在终止占用进程..."
|
|
|
|
|
|
lsof -ti:$port | xargs kill -9
|
|
|
|
|
|
print_success "进程已终止"
|
|
|
|
|
|
else
|
|
|
|
|
|
print_error "无法启动 n8n,端口被占用"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
fi
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 停止现有的 n8n 进程
|
|
|
|
|
|
stop_existing() {
|
|
|
|
|
|
print_info "正在停止现有的 n8n 进程..."
|
|
|
|
|
|
|
|
|
|
|
|
# 停止可能存在的 pnpm dev 进程
|
|
|
|
|
|
pkill -f "pnpm.*dev" 2>/dev/null || true
|
|
|
|
|
|
pkill -f "pnpm.*start" 2>/dev/null || true
|
|
|
|
|
|
pkill -f "turbo.*dev" 2>/dev/null || true
|
|
|
|
|
|
pkill -f "n8n" 2>/dev/null || true
|
|
|
|
|
|
|
|
|
|
|
|
sleep 2
|
|
|
|
|
|
print_success "已停止现有进程"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 设置环境变量
|
|
|
|
|
|
setup_environment() {
|
|
|
|
|
|
print_info "正在设置环境变量..."
|
|
|
|
|
|
|
|
|
|
|
|
export N8N_DEFAULT_LOCALE=zh-CN
|
|
|
|
|
|
export N8N_SECURE_COOKIE=false
|
|
|
|
|
|
export DB_SQLITE_POOL_SIZE=5
|
|
|
|
|
|
export N8N_RUNNERS_ENABLED=true
|
|
|
|
|
|
export N8N_BLOCK_ENV_ACCESS_IN_NODE=false
|
|
|
|
|
|
|
|
|
|
|
|
print_success "环境变量已设置"
|
|
|
|
|
|
echo " - N8N_DEFAULT_LOCALE=zh-CN"
|
|
|
|
|
|
echo " - N8N_SECURE_COOKIE=false"
|
|
|
|
|
|
echo " - DB_SQLITE_POOL_SIZE=5"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 检查构建状态
|
|
|
|
|
|
check_build() {
|
|
|
|
|
|
if [ ! -d "packages/cli/dist" ] || [ ! -d "packages/core/dist" ]; then
|
|
|
|
|
|
print_warning "检测到项目需要构建"
|
|
|
|
|
|
read -p "是否现在构建项目?这可能需要几分钟时间 (y/N): " build_project
|
|
|
|
|
|
|
|
|
|
|
|
if [[ $build_project =~ ^[Yy]$ ]]; then
|
|
|
|
|
|
print_info "正在构建项目..."
|
|
|
|
|
|
pnpm build > build.log 2>&1 &
|
|
|
|
|
|
BUILD_PID=$!
|
|
|
|
|
|
|
|
|
|
|
|
# 显示构建进度
|
|
|
|
|
|
while kill -0 $BUILD_PID 2>/dev/null; do
|
|
|
|
|
|
echo -n "."
|
|
|
|
|
|
sleep 2
|
|
|
|
|
|
done
|
|
|
|
|
|
echo
|
|
|
|
|
|
|
|
|
|
|
|
if wait $BUILD_PID; then
|
|
|
|
|
|
print_success "项目构建完成"
|
|
|
|
|
|
else
|
|
|
|
|
|
print_error "构建失败,请查看 build.log"
|
|
|
|
|
|
tail -20 build.log
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
fi
|
|
|
|
|
|
fi
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 启动 n8n
|
|
|
|
|
|
start_n8n() {
|
|
|
|
|
|
print_info "正在启动 n8n 中文版..."
|
|
|
|
|
|
|
|
|
|
|
|
# 创建日志文件
|
|
|
|
|
|
local log_file="n8n-$(date +%Y%m%d-%H%M%S).log"
|
|
|
|
|
|
|
|
|
|
|
|
# 启动 n8n
|
|
|
|
|
|
echo -e "${GREEN}正在启动 n8n 服务...${NC}"
|
|
|
|
|
|
pnpm start > "$log_file" 2>&1 &
|
|
|
|
|
|
N8N_PID=$!
|
|
|
|
|
|
|
|
|
|
|
|
# 等待启动
|
|
|
|
|
|
echo -n "等待 n8n 启动"
|
|
|
|
|
|
for i in {1..30}; do
|
|
|
|
|
|
if curl -s http://localhost:5678 >/dev/null 2>&1; then
|
|
|
|
|
|
break
|
|
|
|
|
|
fi
|
|
|
|
|
|
echo -n "."
|
|
|
|
|
|
sleep 1
|
|
|
|
|
|
done
|
|
|
|
|
|
echo
|
|
|
|
|
|
|
|
|
|
|
|
# 检查是否启动成功
|
|
|
|
|
|
if curl -s http://localhost:5678 >/dev/null 2>&1; then
|
|
|
|
|
|
print_success "n8n 启动成功!"
|
|
|
|
|
|
echo
|
|
|
|
|
|
echo -e "${GREEN}========== 启动信息 ==========${NC}"
|
|
|
|
|
|
echo -e "📱 访问地址: ${BLUE}http://localhost:5678${NC}"
|
|
|
|
|
|
echo -e "🌏 界面语言: ${GREEN}中文 (zh-CN)${NC}"
|
|
|
|
|
|
echo -e "📋 进程 PID: ${YELLOW}$N8N_PID${NC}"
|
|
|
|
|
|
echo -e "📝 日志文件: ${YELLOW}$log_file${NC}"
|
|
|
|
|
|
echo -e "${GREEN}=============================${NC}"
|
|
|
|
|
|
echo
|
|
|
|
|
|
print_info "使用 Ctrl+C 停止服务"
|
|
|
|
|
|
|
|
|
|
|
|
# 保持脚本运行并显示日志
|
|
|
|
|
|
trap 'print_info "正在停止 n8n..."; kill $N8N_PID 2>/dev/null; exit 0' INT
|
|
|
|
|
|
tail -f "$log_file"
|
|
|
|
|
|
else
|
|
|
|
|
|
print_error "n8n 启动失败"
|
|
|
|
|
|
print_info "查看日志文件: $log_file"
|
|
|
|
|
|
tail -20 "$log_file"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 显示使用帮助
|
|
|
|
|
|
show_help() {
|
|
|
|
|
|
echo "用法: $0 [选项]"
|
|
|
|
|
|
echo
|
|
|
|
|
|
echo "选项:"
|
|
|
|
|
|
echo " -h, --help 显示此帮助信息"
|
|
|
|
|
|
echo " -d, --dev 使用开发模式启动 (支持热重载)"
|
|
|
|
|
|
echo " -b, --build 强制重新构建项目"
|
|
|
|
|
|
echo " -c, --check 仅检查系统状态,不启动"
|
|
|
|
|
|
echo
|
|
|
|
|
|
echo "示例:"
|
|
|
|
|
|
echo " $0 # 正常启动"
|
|
|
|
|
|
echo " $0 -d # 开发模式启动"
|
|
|
|
|
|
echo " $0 -b # 重新构建并启动"
|
|
|
|
|
|
echo
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-08 08:22:54 +08:00
|
|
|
|
# 检查并切换到正确目录
|
|
|
|
|
|
check_and_change_directory() {
|
|
|
|
|
|
local current_dir="$(pwd)"
|
|
|
|
|
|
local script_path="$(readlink -f "$0" 2>/dev/null || realpath "$0" 2>/dev/null || echo "$0")"
|
|
|
|
|
|
local script_dir="$(dirname "$script_path")"
|
|
|
|
|
|
local n8n_dir=""
|
|
|
|
|
|
|
|
|
|
|
|
# 如果当前目录已经是 n8n 项目目录
|
|
|
|
|
|
if [[ -f "package.json" && -d "packages" ]]; then
|
|
|
|
|
|
print_info "检测到当前已在 n8n 项目目录"
|
|
|
|
|
|
return 0
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 如果脚本在 n8n-n8n-1.109.2 目录内,则使用脚本所在目录
|
|
|
|
|
|
if [[ "$script_dir" == *"n8n-n8n-1.109.2"* ]]; then
|
|
|
|
|
|
print_info "切换到脚本所在的 n8n 项目目录: $script_dir"
|
|
|
|
|
|
cd "$script_dir" || {
|
|
|
|
|
|
print_error "无法切换到目录: $script_dir"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
}
|
|
|
|
|
|
print_success "已切换到正确的 n8n 项目目录"
|
|
|
|
|
|
return 0
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 尝试找到 n8n-n8n-1.109.2 目录
|
|
|
|
|
|
if [ -d "./n8n-n8n-1.109.2" ]; then
|
|
|
|
|
|
n8n_dir="./n8n-n8n-1.109.2"
|
|
|
|
|
|
elif [ -d "../n8n-n8n-1.109.2" ]; then
|
|
|
|
|
|
n8n_dir="../n8n-n8n-1.109.2"
|
|
|
|
|
|
elif [ -d "../../n8n-n8n-1.109.2" ]; then
|
|
|
|
|
|
n8n_dir="../../n8n-n8n-1.109.2"
|
|
|
|
|
|
else
|
|
|
|
|
|
print_error "未找到 n8n-n8n-1.109.2 目录"
|
|
|
|
|
|
print_info "请确保在正确的项目目录下运行此脚本"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
print_info "切换到 n8n 项目目录: $n8n_dir"
|
|
|
|
|
|
cd "$n8n_dir" || {
|
|
|
|
|
|
print_error "无法切换到目录: $n8n_dir"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 验证目录结构
|
|
|
|
|
|
if [ ! -f "package.json" ] || [ ! -d "packages" ]; then
|
|
|
|
|
|
print_error "目录结构不正确,缺少 package.json 或 packages 目录"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
print_success "已切换到正确的 n8n 项目目录"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-08 07:21:48 +08:00
|
|
|
|
# 主函数
|
|
|
|
|
|
main() {
|
|
|
|
|
|
# 解析命令行参数
|
|
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
|
|
|
|
case $1 in
|
|
|
|
|
|
-h|--help)
|
|
|
|
|
|
show_help
|
|
|
|
|
|
exit 0
|
|
|
|
|
|
;;
|
|
|
|
|
|
-d|--dev)
|
|
|
|
|
|
DEV_MODE=true
|
|
|
|
|
|
shift
|
|
|
|
|
|
;;
|
|
|
|
|
|
-b|--build)
|
|
|
|
|
|
FORCE_BUILD=true
|
|
|
|
|
|
shift
|
|
|
|
|
|
;;
|
|
|
|
|
|
-c|--check)
|
|
|
|
|
|
CHECK_ONLY=true
|
|
|
|
|
|
shift
|
|
|
|
|
|
;;
|
|
|
|
|
|
*)
|
|
|
|
|
|
print_error "未知选项: $1"
|
|
|
|
|
|
show_help
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
;;
|
|
|
|
|
|
esac
|
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
|
|
# 显示横幅
|
|
|
|
|
|
show_banner
|
|
|
|
|
|
|
2025-09-08 08:22:54 +08:00
|
|
|
|
# 检查并切换到正确目录
|
|
|
|
|
|
check_and_change_directory
|
|
|
|
|
|
|
2025-09-08 07:21:48 +08:00
|
|
|
|
# 检查依赖
|
|
|
|
|
|
check_dependencies
|
|
|
|
|
|
|
|
|
|
|
|
# 检查端口
|
|
|
|
|
|
check_port
|
|
|
|
|
|
|
|
|
|
|
|
# 停止现有进程
|
|
|
|
|
|
stop_existing
|
|
|
|
|
|
|
|
|
|
|
|
# 设置环境变量
|
|
|
|
|
|
setup_environment
|
|
|
|
|
|
|
|
|
|
|
|
# 仅检查模式
|
|
|
|
|
|
if [ "$CHECK_ONLY" = true ]; then
|
|
|
|
|
|
print_success "系统状态检查完成,一切正常"
|
|
|
|
|
|
exit 0
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 强制构建或检查构建状态
|
|
|
|
|
|
if [ "$FORCE_BUILD" = true ]; then
|
|
|
|
|
|
print_info "强制重新构建项目..."
|
|
|
|
|
|
pnpm build
|
|
|
|
|
|
print_success "构建完成"
|
|
|
|
|
|
else
|
|
|
|
|
|
check_build
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 开发模式
|
|
|
|
|
|
if [ "$DEV_MODE" = true ]; then
|
|
|
|
|
|
print_info "正在以开发模式启动 n8n..."
|
|
|
|
|
|
print_warning "开发模式启动时间较长,请耐心等待..."
|
|
|
|
|
|
exec pnpm dev
|
|
|
|
|
|
else
|
|
|
|
|
|
# 正常启动
|
|
|
|
|
|
start_n8n
|
|
|
|
|
|
fi
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 运行主函数
|
|
|
|
|
|
main "$@"
|