You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
400 lines
8.7 KiB
400 lines
8.7 KiB
#!/bin/bash
|
|
# Linux 离线打包脚本 - 开发模式部署
|
|
|
|
APP_NAME="wuyuanbiaoba-web"
|
|
|
|
# 读取版本号
|
|
if [ -f package.json ]; then
|
|
VERSION=$(grep '"version"' package.json | head -1 | sed -E 's/.*"version": *"([^"]+)".*/\1/')
|
|
[ -z "$VERSION" ] && VERSION="latest"
|
|
else
|
|
VERSION="latest"
|
|
fi
|
|
|
|
TARGET_DIR="./build"
|
|
DEPLOY_PACKAGE="${APP_NAME}-${VERSION}-offline.tar.gz"
|
|
|
|
echo "================================================"
|
|
echo "🚀 Linux 离线打包"
|
|
echo "================================================"
|
|
echo "应用: $APP_NAME"
|
|
echo "版本: $VERSION"
|
|
echo ""
|
|
|
|
# 检查必要工具
|
|
check_command() {
|
|
if ! command -v $1 &> /dev/null; then
|
|
echo "❌ 错误: 未找到 $1 命令"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
check_command "node"
|
|
check_command "npm"
|
|
check_command "tar"
|
|
|
|
echo "✅ 环境检查通过"
|
|
echo " Node.js: $(node -v)"
|
|
echo " npm: $(npm -v)"
|
|
echo ""
|
|
|
|
# 清理旧构建
|
|
echo "🧹 清理旧构建..."
|
|
rm -rf $TARGET_DIR
|
|
rm -f *.tar.gz
|
|
mkdir -p $TARGET_DIR
|
|
|
|
# 复制源代码
|
|
echo ""
|
|
echo "📁 复制源代码..."
|
|
|
|
REQUIRED_FILES=(
|
|
"package.json"
|
|
"package-lock.json"
|
|
"index.html"
|
|
"config.cjs"
|
|
)
|
|
|
|
REQUIRED_DIRS=(
|
|
"client"
|
|
"server"
|
|
"script"
|
|
)
|
|
|
|
# 复制文件
|
|
for file in "${REQUIRED_FILES[@]}"; do
|
|
if [ -f "$file" ]; then
|
|
cp "$file" "$TARGET_DIR/"
|
|
echo " ✅ $file"
|
|
else
|
|
echo " ⚠️ 警告: 缺少 $file"
|
|
fi
|
|
done
|
|
|
|
# 复制目录
|
|
for dir in "${REQUIRED_DIRS[@]}"; do
|
|
if [ -d "$dir" ]; then
|
|
cp -r "$dir" "$TARGET_DIR/"
|
|
echo " ✅ $dir/"
|
|
else
|
|
echo " ⚠️ 警告: 缺少 $dir/"
|
|
fi
|
|
done
|
|
|
|
# 复制 README(可选)
|
|
[ -f README.md ] && cp README.md "$TARGET_DIR/" && echo " ✅ README.md"
|
|
|
|
# 安装依赖(包括 devDependencies,因为开发模式需要)
|
|
echo ""
|
|
echo "📦 安装依赖 (包括开发依赖)..."
|
|
echo " 这可能需要几分钟..."
|
|
echo ""
|
|
|
|
cd $TARGET_DIR
|
|
|
|
# 使用 npm install 安装所有依赖(不是 --production)
|
|
echo "安装依赖..."
|
|
npm install
|
|
|
|
if [ $? -ne 0 ]; then
|
|
echo "❌ npm 安装失败"
|
|
exit 1
|
|
fi
|
|
|
|
cd ..
|
|
|
|
echo ""
|
|
echo "✅ node_modules 安装完成"
|
|
echo " 大小: $(du -sh $TARGET_DIR/node_modules | cut -f1)"
|
|
|
|
# 创建部署脚本(参照 package-app.sh 的逻辑)
|
|
echo ""
|
|
echo "📝 生成部署脚本..."
|
|
|
|
cat > $TARGET_DIR/deploy.sh << 'DEPLOY_EOF'
|
|
#!/bin/bash
|
|
# 应用部署脚本(离线版本,开发模式)
|
|
|
|
APP_NAME="wuyuanbiaoba-web"
|
|
INSTALL_DIR="/opt/$APP_NAME"
|
|
SERVICE_NAME="$APP_NAME.service"
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
echo "================================================"
|
|
echo "🚀 部署 $APP_NAME (离线开发模式)"
|
|
echo "================================================"
|
|
|
|
# Root 权限检查
|
|
if [ "$EUID" -ne 0 ]; then
|
|
echo "❌ 错误: 需要 root 权限"
|
|
echo " 使用: sudo ./deploy.sh"
|
|
exit 1
|
|
fi
|
|
|
|
# systemd 检查
|
|
if ! pidof systemd &>/dev/null; then
|
|
echo "❌ 错误: 系统不支持 systemd"
|
|
exit 1
|
|
fi
|
|
|
|
# 检查 Node.js 环境
|
|
echo ""
|
|
echo "🔍 检查 Node.js 环境..."
|
|
|
|
if ! command -v node &> /dev/null; then
|
|
echo "❌ 错误: 未安装 Node.js"
|
|
echo " 请先安装 Node.js 20 或更高版本"
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v npm &> /dev/null; then
|
|
echo "❌ 错误: 未安装 npm"
|
|
exit 1
|
|
fi
|
|
|
|
NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
|
|
if [ "$NODE_VERSION" -lt 20 ]; then
|
|
echo "❌ 错误: Node.js 版本过低 ($(node -v))"
|
|
echo " 需要 Node.js 20 或更高版本"
|
|
exit 1
|
|
fi
|
|
|
|
echo " ✅ Node.js: $(node -v)"
|
|
echo " ✅ npm: $(npm -v)"
|
|
|
|
# 部署应用
|
|
echo ""
|
|
echo "🛠️ 开始部署..."
|
|
|
|
# 停止服务
|
|
if systemctl is-active --quiet $SERVICE_NAME; then
|
|
echo " 停止服务..."
|
|
systemctl stop $SERVICE_NAME
|
|
sleep 2
|
|
fi
|
|
|
|
if systemctl is-enabled --quiet $SERVICE_NAME 2>/dev/null; then
|
|
echo " 禁用服务..."
|
|
systemctl disable $SERVICE_NAME 2>/dev/null
|
|
fi
|
|
|
|
# 清理旧备份(保留7天内的)
|
|
if [ -d "/opt" ]; then
|
|
echo " 清理旧备份..."
|
|
find /opt -maxdepth 1 -name "${APP_NAME}_backup_*" -type d -mtime +7 -exec rm -rf {} \; 2>/dev/null || true
|
|
fi
|
|
|
|
# 备份现有版本
|
|
if [ -d "$INSTALL_DIR" ]; then
|
|
BACKUP_DIR="${INSTALL_DIR}_backup_$(date +%Y%m%d_%H%M%S)"
|
|
echo " 备份到: $BACKUP_DIR"
|
|
mv "$INSTALL_DIR" "$BACKUP_DIR"
|
|
fi
|
|
|
|
# 创建安装目录
|
|
mkdir -p $INSTALL_DIR
|
|
|
|
# 复制应用文件
|
|
echo " 复制文件..."
|
|
|
|
# 创建文件清单,确保只复制打包时包含的文件
|
|
REQUIRED_FILES=(
|
|
"package.json"
|
|
"package-lock.json"
|
|
"index.html"
|
|
"config.cjs"
|
|
)
|
|
|
|
REQUIRED_DIRS=(
|
|
"client"
|
|
"server"
|
|
"script"
|
|
"node_modules"
|
|
)
|
|
|
|
# 复制必需文件
|
|
for file in "${REQUIRED_FILES[@]}"; do
|
|
if [ -f "$SCRIPT_DIR/$file" ]; then
|
|
cp "$SCRIPT_DIR/$file" "$INSTALL_DIR/"
|
|
echo " ✅ $file"
|
|
else
|
|
echo " ⚠️ 警告: 缺少 $file"
|
|
fi
|
|
done
|
|
|
|
# 复制必需目录
|
|
for dir in "${REQUIRED_DIRS[@]}"; do
|
|
if [ -d "$SCRIPT_DIR/$dir" ]; then
|
|
cp -r "$SCRIPT_DIR/$dir" "$INSTALL_DIR/"
|
|
echo " ✅ $dir/"
|
|
else
|
|
echo " ⚠️ 警告: 缺少 $dir"
|
|
fi
|
|
done
|
|
|
|
# 复制可选文件
|
|
[ -f "$SCRIPT_DIR/README.md" ] && cp "$SCRIPT_DIR/README.md" "$INSTALL_DIR/" && echo " ✅ README.md"
|
|
|
|
# 验证关键文件
|
|
echo ""
|
|
echo "🔍 验证部署..."
|
|
|
|
MISSING=0
|
|
REQUIRED_CHECK=(
|
|
"package.json"
|
|
"node_modules"
|
|
"server"
|
|
"client"
|
|
"index.html"
|
|
"config.cjs"
|
|
)
|
|
|
|
for item in "${REQUIRED_CHECK[@]}"; do
|
|
if [ ! -e "$INSTALL_DIR/$item" ]; then
|
|
echo " ❌ 缺少: $item"
|
|
MISSING=1
|
|
else
|
|
echo " ✅ $item"
|
|
fi
|
|
done
|
|
|
|
if [ $MISSING -eq 1 ]; then
|
|
echo ""
|
|
echo "❌ 部署验证失败"
|
|
exit 1
|
|
fi
|
|
|
|
# 验证关键依赖
|
|
if [ ! -d "$INSTALL_DIR/node_modules/@peace/react_client" ]; then
|
|
echo " ⚠️ 警告: 缺少关键依赖 @peace/react_client"
|
|
fi
|
|
|
|
# 获取 npm 和 node 的完整路径
|
|
NPM_PATH=$(which npm)
|
|
NODE_PATH=$(which node)
|
|
|
|
echo ""
|
|
echo "⚙️ 配置服务..."
|
|
echo " Node: $NODE_PATH"
|
|
echo " npm: $NPM_PATH"
|
|
|
|
# 设置 systemd 环境变量
|
|
SYSTEMD_PATH="/usr/local/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin"
|
|
|
|
# 创建启动脚本
|
|
cat > $INSTALL_DIR/start.sh << STARTEOF
|
|
#!/bin/bash
|
|
cd $INSTALL_DIR
|
|
export NODE_ENV=development
|
|
export PATH=$SYSTEMD_PATH
|
|
exec $NPM_PATH start
|
|
STARTEOF
|
|
|
|
chmod +x $INSTALL_DIR/start.sh
|
|
|
|
# 创建 systemd 服务文件(开发模式)
|
|
cat > /etc/systemd/system/$SERVICE_NAME << SERVICE_EOF
|
|
[Unit]
|
|
Description=$APP_NAME Node.js Application
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=root
|
|
WorkingDirectory=$INSTALL_DIR
|
|
ExecStart=$INSTALL_DIR/start.sh
|
|
Restart=on-failure
|
|
RestartSec=10
|
|
Environment=NODE_ENV=development
|
|
Environment=PATH=$SYSTEMD_PATH
|
|
|
|
StandardOutput=journal
|
|
StandardError=journal
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
SERVICE_EOF
|
|
|
|
# 重新加载 systemd
|
|
systemctl daemon-reload
|
|
|
|
# 启用并启动服务
|
|
systemctl enable $SERVICE_NAME
|
|
systemctl start $SERVICE_NAME
|
|
|
|
# 等待服务启动
|
|
sleep 3
|
|
|
|
echo ""
|
|
echo "================================================"
|
|
echo "📊 部署结果"
|
|
echo "================================================"
|
|
systemctl status $SERVICE_NAME --no-pager
|
|
|
|
# 清理部署目录(如果在 /tmp 下)
|
|
DEPLOY_DIR="$SCRIPT_DIR"
|
|
if [[ "$DEPLOY_DIR" == "/tmp/"* ]]; then
|
|
echo ""
|
|
echo "🗑️ 清理部署临时目录: $DEPLOY_DIR"
|
|
cd /tmp
|
|
rm -rf "$DEPLOY_DIR"
|
|
fi
|
|
|
|
echo ""
|
|
echo "================================================"
|
|
echo "✅ 部署完成!"
|
|
echo "================================================"
|
|
echo ""
|
|
echo "📌 常用命令:"
|
|
echo " 状态: systemctl status $SERVICE_NAME"
|
|
echo " 日志: journalctl -u $SERVICE_NAME -f"
|
|
echo " 重启: systemctl restart $SERVICE_NAME"
|
|
echo " 停止: systemctl stop $SERVICE_NAME"
|
|
echo ""
|
|
DEPLOY_EOF
|
|
|
|
chmod +x $TARGET_DIR/deploy.sh
|
|
|
|
# 创建打包
|
|
echo ""
|
|
echo "📦 创建离线部署包..."
|
|
echo ""
|
|
|
|
cd $TARGET_DIR
|
|
tar -czf ../$DEPLOY_PACKAGE . 2>&1 | grep -v "tar: Removing leading"
|
|
cd ..
|
|
|
|
if [ ! -f "$DEPLOY_PACKAGE" ]; then
|
|
echo "❌ 打包失败"
|
|
exit 1
|
|
fi
|
|
|
|
PACKAGE_SIZE=$(du -h $DEPLOY_PACKAGE | cut -f1)
|
|
|
|
echo ""
|
|
echo "================================================"
|
|
echo "✅ 打包完成!"
|
|
echo "================================================"
|
|
echo ""
|
|
echo "📦 部署包信息:"
|
|
echo " 文件名: $DEPLOY_PACKAGE"
|
|
echo " 大小: $PACKAGE_SIZE"
|
|
echo " 位置: $(pwd)/$DEPLOY_PACKAGE"
|
|
echo ""
|
|
echo "📋 包含内容:"
|
|
echo " ✅ 应用源代码"
|
|
echo " ✅ node_modules (包括开发依赖)"
|
|
echo " ✅ 部署脚本"
|
|
echo ""
|
|
echo "🎯 部署要求:"
|
|
echo " - Node.js >= 20.0.0"
|
|
echo " - npm"
|
|
echo " - systemd"
|
|
echo ""
|
|
echo "🎯 部署步骤:"
|
|
echo " 1. 上传到目标服务器"
|
|
echo " 2. 解压: tar -xzf $DEPLOY_PACKAGE"
|
|
echo " 3. 部署: sudo ./deploy.sh"
|
|
echo ""
|
|
echo "💡 此包以开发模式运行,包含所有依赖"
|
|
echo ""
|
|
|