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.
295 lines
6.9 KiB
295 lines
6.9 KiB
#!/bin/bash
|
|
# 应用打包脚本 - 在开发环境运行
|
|
|
|
APP_NAME="wuyuanbiaoba-web"
|
|
# 自动读取 package.json 的 version 字段,如果失败则用 latest
|
|
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}.tar.gz"
|
|
|
|
echo "打包 Node.js 应用..."
|
|
|
|
# 清理旧构建
|
|
rm -rf $TARGET_DIR
|
|
mkdir -p $TARGET_DIR
|
|
|
|
# 复制源代码
|
|
# 复制文件
|
|
cp package.json $TARGET_DIR/
|
|
cp package-lock.json $TARGET_DIR/
|
|
cp index.html $TARGET_DIR/
|
|
cp config.cjs $TARGET_DIR/
|
|
[ -f README.md ] && cp README.md $TARGET_DIR/
|
|
|
|
# 复制目录
|
|
cp -r client/ $TARGET_DIR/
|
|
cp -r server/ $TARGET_DIR/
|
|
cp -r script/ $TARGET_DIR/
|
|
# 创建部署脚本
|
|
cat > $TARGET_DIR/deploy.sh << 'EOF'
|
|
#!/bin/bash
|
|
# 应用部署脚本
|
|
|
|
APP_NAME="wuyuanbiaoba-web"
|
|
INSTALL_DIR="/opt/$APP_NAME"
|
|
SERVICE_NAME="$APP_NAME.service"
|
|
NODE_VERSION="20.19.3"
|
|
|
|
echo "正在部署 $APP_NAME..."
|
|
|
|
# 检查是否为 root 权限
|
|
if [ "$EUID" -ne 0 ]; then
|
|
echo "错误: 请使用 root 权限运行此脚本 (sudo ./deploy.sh)"
|
|
exit 1
|
|
fi
|
|
|
|
# 检查 systemd 是否可用
|
|
if ! pidof systemd &>/dev/null; then
|
|
echo "错误: 当前系统不支持 systemd"
|
|
exit 1
|
|
fi
|
|
|
|
# 自动安装 Node.js 函数
|
|
install_nodejs() {
|
|
echo "正在自动安装 Node.js $NODE_VERSION..."
|
|
|
|
# 检测系统架构
|
|
ARCH=$(uname -m)
|
|
case $ARCH in
|
|
x86_64)
|
|
NODE_ARCH="x64"
|
|
;;
|
|
aarch64)
|
|
NODE_ARCH="arm64"
|
|
;;
|
|
armv7l)
|
|
NODE_ARCH="armv7l"
|
|
;;
|
|
*)
|
|
echo "错误: 不支持的系统架构: $ARCH"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
NODE_PACKAGE="node-v$NODE_VERSION-linux-$NODE_ARCH"
|
|
DOWNLOAD_URL="https://nodejs.org/dist/v$NODE_VERSION/$NODE_PACKAGE.tar.xz"
|
|
|
|
# 创建临时目录
|
|
cd /tmp
|
|
|
|
# 下载 Node.js
|
|
echo "下载 Node.js..."
|
|
if ! wget -q --show-progress "$DOWNLOAD_URL"; then
|
|
echo "错误: 下载 Node.js 失败,请检查网络连接"
|
|
exit 1
|
|
fi
|
|
|
|
# 解压并安装
|
|
echo "安装 Node.js..."
|
|
tar -xJf "$NODE_PACKAGE.tar.xz"
|
|
mv "$NODE_PACKAGE" "/usr/local/node-v$NODE_VERSION"
|
|
|
|
# 创建软链接
|
|
ln -sf "/usr/local/node-v$NODE_VERSION/bin/node" /usr/local/bin/node
|
|
ln -sf "/usr/local/node-v$NODE_VERSION/bin/npm" /usr/local/bin/npm
|
|
ln -sf "/usr/local/node-v$NODE_VERSION/bin/npx" /usr/local/bin/npx
|
|
|
|
# 清理下载文件
|
|
rm -f "/tmp/$NODE_PACKAGE.tar.xz"
|
|
|
|
# 验证安装
|
|
if node -v && npm -v; then
|
|
echo "Node.js 安装成功!"
|
|
echo "Node.js 版本: $(node -v)"
|
|
echo "npm 版本: $(npm -v)"
|
|
else
|
|
echo "错误: Node.js 安装失败"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# 检查 Node.js 是否安装
|
|
if ! command -v node &> /dev/null; then
|
|
echo "未检测到 Node.js,将自动安装..."
|
|
install_nodejs
|
|
else
|
|
# 检查 Node.js 版本
|
|
CURRENT_NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
|
|
if [ "$CURRENT_NODE_VERSION" -lt 20 ]; then
|
|
echo "当前 Node.js 版本过低 ($(node -v)),将自动升级到 v$NODE_VERSION..."
|
|
install_nodejs
|
|
else
|
|
echo "检测到 Node.js 版本: $(node -v)"
|
|
fi
|
|
fi
|
|
|
|
# 检查 npm 是否可用
|
|
if ! command -v npm &> /dev/null; then
|
|
echo "错误: npm 不可用,请检查 Node.js 安装"
|
|
exit 1
|
|
fi
|
|
|
|
# 停止现有服务
|
|
if systemctl is-active --quiet $SERVICE_NAME; then
|
|
echo "停止现有服务..."
|
|
systemctl stop $SERVICE_NAME
|
|
sleep 2
|
|
fi
|
|
|
|
# 禁用现有服务
|
|
if systemctl is-enabled --quiet $SERVICE_NAME; then
|
|
echo "禁用现有服务..."
|
|
systemctl disable $SERVICE_NAME
|
|
fi
|
|
|
|
# 清理超过7天的旧备份
|
|
if [ -d "/opt" ]; then
|
|
echo "清理超过7天的旧备份..."
|
|
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"
|
|
"README.md"
|
|
)
|
|
|
|
REQUIRED_DIRS=(
|
|
"client"
|
|
"server"
|
|
"script"
|
|
)
|
|
|
|
# 复制必需文件
|
|
for file in "${REQUIRED_FILES[@]}"; do
|
|
if [ -f "$file" ]; then
|
|
cp "$file" "$INSTALL_DIR/"
|
|
echo "已复制: $file"
|
|
else
|
|
echo "警告: 缺少文件 $file"
|
|
fi
|
|
done
|
|
|
|
# 复制必需目录
|
|
for dir in "${REQUIRED_DIRS[@]}"; do
|
|
if [ -d "$dir" ]; then
|
|
cp -r "$dir/" "$INSTALL_DIR/"
|
|
echo "已复制目录: $dir/"
|
|
else
|
|
echo "警告: 缺少目录 $dir"
|
|
fi
|
|
done
|
|
|
|
# 复制可选配置文件(如果存在)
|
|
OPTIONAL_FILES=(".env" ".npmrc" ".editorconfig")
|
|
for file in "${OPTIONAL_FILES[@]}"; do
|
|
if [ -f "$file" ]; then
|
|
cp "$file" "$INSTALL_DIR/"
|
|
echo "已复制配置文件: $file"
|
|
fi
|
|
done
|
|
|
|
# 验证关键文件
|
|
if [ ! -f "$INSTALL_DIR/package.json" ]; then
|
|
echo "错误: package.json 复制失败"
|
|
exit 1
|
|
fi
|
|
|
|
echo "文件复制完成,安装目录内容:"
|
|
ls -la "$INSTALL_DIR/"
|
|
|
|
# 安装依赖
|
|
echo "安装依赖包..."
|
|
cd $INSTALL_DIR
|
|
npm install
|
|
|
|
# 检查主入口文件
|
|
if [ ! -f "package.json" ]; then
|
|
echo "错误: package.json 文件不存在"
|
|
exit 1
|
|
fi
|
|
|
|
# 获取 npm 和 node 的完整路径
|
|
NPM_PATH=$(which npm)
|
|
NODE_PATH=$(which node)
|
|
|
|
echo "使用 Node.js: $NODE_PATH"
|
|
echo "使用 npm: $NPM_PATH"
|
|
|
|
# 设置 systemd 环境变量
|
|
SYSTEMD_PATH="/usr/local/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin"
|
|
EXEC_START="$NPM_PATH start"
|
|
|
|
# 创建 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=$EXEC_START
|
|
Restart=on-failure
|
|
RestartSec=10
|
|
Environment=NODE_ENV=development
|
|
Environment=PATH=$SYSTEMD_PATH
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
SERVICE_EOF
|
|
|
|
# 重新加载 systemd
|
|
systemctl daemon-reload
|
|
|
|
# 启用并启动服务
|
|
systemctl enable $SERVICE_NAME
|
|
systemctl start $SERVICE_NAME
|
|
|
|
# 等待服务启动
|
|
sleep 3
|
|
|
|
echo "部署完成! 服务状态:"
|
|
systemctl status $SERVICE_NAME --no-pager
|
|
|
|
# 清理部署目录(自动清理)
|
|
DEPLOY_DIR=$(pwd)
|
|
if [[ "$DEPLOY_DIR" == "/tmp/"* ]]; then
|
|
echo "清理部署临时目录: $DEPLOY_DIR"
|
|
cd /tmp
|
|
rm -rf "$DEPLOY_DIR"
|
|
fi
|
|
|
|
echo ""
|
|
echo "✅ 部署成功!"
|
|
echo "🔍 查看服务状态: systemctl status $SERVICE_NAME"
|
|
echo "📋 查看实时日志: journalctl -u $SERVICE_NAME -f"
|
|
EOF
|
|
|
|
# 创建打包文件
|
|
tar -czf $DEPLOY_PACKAGE -C $TARGET_DIR .
|
|
|
|
echo "打包完成: $DEPLOY_PACKAGE"
|
|
echo "请将此文件上传到服务器并解压后运行 ./deploy.sh"
|
|
|