Skip to content

VitePress 网站部署完整指南

前言

本指南详细记录了将基于 VitePress 的笔记网站部署到 Ubuntu 22.04 服务器的完整过程,包括实际遇到的问题、解决方案和最佳实践。通过 HTTP 8080 端口提供服务,支持 Git 自动化部署。

网络架构说明

在云服务器环境中,您会遇到以下网络配置:

外部访问路径:
Internet → 公网IP(43.159.60.248) → 云服务商网关 → 内网IP → 您的服务器

实际情况:
- 外部访问使用:43.159.60.248
- ifconfig 显示:10.0.4.12 (内网IP)
- 应用需要监听:0.0.0.0 (所有接口)

端口规划

  • 8080端口:Nginx 生产环境(静态文件)
  • 3000端口:VitePress 开发服务器(实时预览)
  • 22端口:SSH 远程连接

第一阶段:环境准备

1. 服务器连接和用户设置

1.1 连接服务器

bash
ssh username@43.159.60.248

1.2 创建专用用户

bash
sudo adduser webnote
sudo usermod -aG sudo webnote
su - webnote

1.3 创建目录结构

bash
mkdir -p ~/webnote/{source,build,logs}
cd ~/webnote

2. Node.js 环境配置

2.1 安装 Node.js 20.x LTS

bash
# 移除旧版本
sudo apt-get remove nodejs npm -y

# 安装 Node.js 20.x
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs

# 验证安装
node --version  # 应显示 v20.x.x
npm --version

2.2 安装全局工具

bash
sudo npm install -g pm2
sudo apt install nginx -y

第二阶段:项目部署

3. 代码上传和Git配置

3.1 从本地上传项目

bash
# 在本地 Windows 机器执行
scp -r d:\github_vs\WebNote webnote@43.159.60.248:~/webnote/source/

3.2 在服务器初始化Git

bash
cd ~/webnote/source/WebNote
git init
git add .
git commit -m "Initial commit: VitePress website"

# 创建裸仓库用于接收推送
cd ~/webnote
git clone --bare source/WebNote webnote.git

4. 配置自动部署钩子

4.1 创建智能部署脚本

bash
nano ~/webnote/webnote.git/hooks/post-receive

添加以下内容:

bash
#!/bin/bash
# Git post-receive 钩子:自动部署 VitePress 网站

set -e

echo "=== Starting Auto Deployment ==="

# 工作目录
WORK_DIR="/home/webnote/webnote/source/WebNote"
BUILD_DIR="/home/webnote/webnote/build"
LOG_DIR="/home/webnote/webnote/logs"

# 记录部署日志
echo "$(date): Received Git push, starting deployment" >> $LOG_DIR/deploy.log

# 更新工作目录
cd $WORK_DIR
git --git-dir=/home/webnote/webnote/webnote.git --work-tree=$WORK_DIR checkout -f

# 智能判断是否需要安装依赖
if [ -d "node_modules" ]; then
    echo "Detected node_modules exists, skipping npm install"
    echo "$(date): Skipped dependency installation (node_modules exists)" >> $LOG_DIR/deploy.log
else
    echo "1. Installing dependencies..."
    npm install >> $LOG_DIR/deploy.log 2>&1
    echo "$(date): Completed dependency installation" >> $LOG_DIR/deploy.log
fi

echo "2. Building project..."
npm run docs:build >> $LOG_DIR/deploy.log 2>&1

echo "3. Backing up current version..."
if [ -d "$BUILD_DIR" ] && [ "$(ls -A $BUILD_DIR)" ]; then
    cp -r $BUILD_DIR $BUILD_DIR.backup.$(date +%Y%m%d_%H%M%S)
fi

echo "4. Updating build files..."
rm -rf $BUILD_DIR/*
cp -r docs/.vitepress/dist/* $BUILD_DIR/

# 设置正确的权限
echo "4.1 Setting correct permissions..."
chmod 755 /home/webnote
chmod 755 /home/webnote/webnote  
chmod 755 /home/webnote/webnote/build
chmod -R 644 $BUILD_DIR/*
find $BUILD_DIR -type d -exec chmod 755 {} \;

echo "5. Reloading Nginx..."
if sudo systemctl reload nginx 2>/dev/null; then
    echo "   ✅ Nginx reloaded successfully"
    echo "$(date): Nginx reloaded successfully" >> $LOG_DIR/deploy.log
else
    echo "   ⚠️  Nginx reload failed - please run manually: sudo systemctl reload nginx"
    echo "$(date): Nginx reload failed - manual intervention required" >> $LOG_DIR/deploy.log
fi

echo "=== Deployment Completed ==="
echo "🌐 Website available at: http://43.159.60.248:8080"
echo "📋 View logs: tail ~/webnote/logs/deploy.log"
echo "$(date): Deployment completed successfully" >> $LOG_DIR/deploy.log

设置可执行权限:

bash
chmod +x ~/webnote/webnote.git/hooks/post-receive

4.6 解决常见钩子脚本问题

在实际部署过程中,我们可能会遇到以下错误:

remote: === Starting Auto Deployment ===
remote: hooks/post-receive: line 14: /home/webnote/webnote/logs/deploy.log: Permission denied

这是由于日志目录权限问题导致的。为了避免此类问题,我们可以使用一个更健壮的钩子脚本版本:

bash
#!/bin/bash
# Git post-receive 钩子:容错型自动部署 VitePress 网站

echo "=== Starting Auto Deployment ==="

# 工作目录定义
WORK_DIR="/home/webnote/webnote/source/WebNote"
BUILD_DIR="/home/webnote/webnote/build"
LOG_DIR="/home/webnote/webnote/logs"
BACKUP_DIR="/home/webnote/webnote/backups"

# 处理标准输入的Git推送信息,以获取当前提交
read oldrev newrev refname
CURRENT_COMMIT=$newrev
BRANCH=${refname##*/}

# 确保各目录存在
mkdir -p $LOG_DIR $BUILD_DIR $BACKUP_DIR 2>/dev/null

# 日志记录函数,不依赖于文件权限
log_message() {
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> $LOG_DIR/deploy.log 2>/dev/null
}

log_message "开始部署:分支=$BRANCH, 提交=$CURRENT_COMMIT"

# 1. 更新工作目录 - 使用环境变量设置Git上下文
echo "1. 更新工作目录..."
cd $WORK_DIR || { log_message "无法进入工作目录!"; exit 1; }

# 使用Git环境变量,避免依赖工作目录中的.git
export GIT_DIR="/home/webnote/webnote/webnote.git"
export GIT_WORK_TREE="$WORK_DIR"

git checkout -f $BRANCH || {
  log_message "检出最新代码失败!"; 
  exit 1;
}

log_message "已更新工作目录,当前提交: $CURRENT_COMMIT"

# 2. 智能依赖管理
if [ -d "node_modules" ] && [ -f "package-lock.json" ]; then
    echo "2. 检测到node_modules已存在,跳过安装"
    
    # 检查是否有package.json变更
    if git diff --name-only $oldrev $newrev | grep -q "package.json"; then
        echo "   检测到package.json变更,更新依赖..."
        npm install --no-audit --no-fund || log_message "警告:依赖更新失败,继续使用现有依赖"
    fi
else
    echo "2. 安装依赖..."
    npm install --no-audit --no-fund || log_message "警告:依赖安装失败,尝试使用现有文件构建"
fi

# 3. 构建项目
echo "3. 构建项目..."
NODE_OPTIONS="--max-old-space-size=512" npm run docs:build || {
  log_message "构建失败!检查日志获取详情"; 
  exit 1;
}
log_message "构建成功完成"

# 4. 备份当前版本
echo "4. 备份当前版本..."
if [ -d "$BUILD_DIR" ] && [ "$(ls -A $BUILD_DIR 2>/dev/null)" ]; then
    BACKUP_NAME="backup-$(date +%Y%m%d_%H%M%S)"
    mkdir -p $BACKUP_DIR/$BACKUP_NAME
    cp -r $BUILD_DIR/* $BACKUP_DIR/$BACKUP_NAME/ 2>/dev/null || 
      echo "警告:备份失败,继续部署"
    
    # 只保留最近5个备份
    ls -t $BACKUP_DIR | tail -n +6 | xargs -I {} rm -rf $BACKUP_DIR/{}
fi

# 5. 更新构建文件
echo "5. 更新构建文件..."
mkdir -p $BUILD_DIR

# 清空目录但保留目录本身
find $BUILD_DIR -mindepth 1 -delete 2>/dev/null || echo "警告:无法清理构建目录"

# 复制新文件
cp -r docs/.vitepress/dist/* $BUILD_DIR/ || {
  log_message "复制构建文件失败!";
  exit 1;
}
log_message "构建文件已成功复制"

# 6. 权限设置 - 尝试多种方法设置权限
echo "6. 设置权限..."

# 方法1:直接设置
chmod 755 /home/webnote /home/webnote/webnote /home/webnote/webnote/build 2>/dev/null

# 方法2:使用sudo (如果配置了sudoers)
if [ $? -ne 0 ]; then
  sudo chmod 755 /home/webnote /home/webnote/webnote /home/webnote/webnote/build 2>/dev/null || 
    echo "警告:无法设置目录权限,检查sudo配置"
fi

# 递归设置文件和目录权限
find $BUILD_DIR -type f -exec chmod 644 {} \; 2>/dev/null || echo "警告:无法设置文件权限"
find $BUILD_DIR -type d -exec chmod 755 {} \; 2>/dev/null || echo "警告:无法设置目录权限"

# 7. 重载 Nginx
echo "7. 重载 Nginx..."
if sudo systemctl reload nginx 2>/dev/null; then
    echo "   ✅ Nginx 重载成功"
    log_message "Nginx 重载成功"
else
    echo "   ⚠️ Nginx 重载失败 - 请手动执行: sudo systemctl reload nginx"
    log_message "Nginx 重载失败 - 需要手动干预"
fi

# 8. 验证部署
echo "8. 验证部署..."
if [ -f "$BUILD_DIR/index.html" ]; then
    INDEX_SIZE=$(stat -c%s "$BUILD_DIR/index.html" 2>/dev/null || echo "unknown")
    echo "   ✅ index.html 存在 ($INDEX_SIZE 字节)"
    log_message "已验证 index.html 存在 ($INDEX_SIZE 字节)"
    
    # 检查文件计数
    FILE_COUNT=$(find $BUILD_DIR -type f | wc -l)
    log_message "部署了 $FILE_COUNT 个文件"
else
    echo "   ⚠️ 警告:index.html 在构建目录中未找到!"
    log_message "警告:index.html 在构建目录中未找到"
fi

echo "=== 部署完成 ==="
echo "🌐 网站地址: http://43.159.60.248:8080"
echo "📋 构建目录: $BUILD_DIR"
echo "🔄 当前提交: ${CURRENT_COMMIT:0:7}"
log_message "部署成功完成,提交: ${CURRENT_COMMIT:0:7}"

主要改进点:

  1. 移除 set -e:防止因权限错误导致脚本中断
  2. 安全的日志记录:使用函数处理日志,避免权限问题
  3. 自动创建目录:确保日志和构建目录存在
  4. 错误处理:关键步骤添加错误处理逻辑
  5. 验证部署:增加验证步骤,确认部署成功
  6. 详细输出:显示更多有用信息,便于调试

如果您曾经遇到权限相关的错误,这个改进版本的脚本可以更稳健地处理这些情况。

5. Nginx 配置

5.1 创建Nginx站点配置

bash
sudo nano /etc/nginx/sites-available/webnote

添加配置:

nginx
server {
    listen 0.0.0.0:8080;  # 显式监听所有网络接口
    server_name 43.159.60.248 _;  # 主要IP + 默认匹配
    
    root /home/webnote/webnote/build;
    index index.html;
    
    # 启用 gzip 压缩
    gzip on;
    gzip_types text/plain text/css application/javascript application/json;
    
    # 静态文件缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
    
    # 处理 SPA 路由
    location / {
        try_files $uri $uri/ /index.html;
    }
    
    # 错误页面
    error_page 404 /index.html;
    
    # 日志配置
    access_log /var/log/nginx/webnote_access.log;
    error_log /var/log/nginx/webnote_error.log;
}

5.2 启用站点

bash
sudo ln -s /etc/nginx/sites-available/webnote /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
sudo systemctl enable nginx

第三阶段:问题排查和解决

6. 实际遇到的问题及解决方案

问题1:Git Push 冲突

现象:

bash
! [rejected]        master -> master (fetch first)
error: failed to push some refs to '43.159.60.248:~/webnote/webnote.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally.

原因分析:

  • 服务器和本地都有独立的Git提交历史
  • 两个仓库的提交记录不一致导致冲突

解决方案:

bash
# 方案1:强制推送覆盖(推荐,服务器是新环境)
git push -f origin master

# 方案2:合并历史
git pull origin master --allow-unrelated-histories
git push origin master

问题2:Nginx 配置冲突

现象:

bash
nginx: [warn] conflicting server name "43.159.60.248" on 0.0.0.0:8080, ignored

原因分析:

  • 多个Nginx配置文件使用相同的 server_name
  • 默认站点和自定义站点冲突

解决方案:

bash
# 查找冲突配置
sudo grep -r "43.159.60.248" /etc/nginx/

# 删除冲突的默认配置
sudo rm /etc/nginx/sites-enabled/default

# 确保只有目标站点启用
ls -la /etc/nginx/sites-enabled/
# 应该只显示:webnote -> /etc/nginx/sites-available/webnote

问题3:Nginx 500 内部错误

现象:

bash
curl -I http://localhost:8080
HTTP/1.1 500 Internal Server Error

原因分析:

  • www-data 用户无法访问 /home/webnote 目录
  • Linux 系统默认用户目录权限限制

解决方案:

bash
# 设置目录权限让 nginx 可以访问
sudo chmod 755 /home/webnote
sudo chmod 755 /home/webnote/webnote
sudo chmod 755 /home/webnote/webnote/build

# 验证权限
sudo -u www-data test -r /home/webnote/webnote/build/index.html && echo "✅ Can read" || echo "❌ Cannot read"

问题4:权限不足 (vitepress: Permission denied)

现象:

bash
sh: 1: vitepress: Permission denied

原因分析:

  • node_modules 中的可执行文件权限不正确
  • Windows 到 Linux 的文件权限映射问题

解决方案:

bash
# 重新安装依赖包获得正确权限
rm -rf node_modules package-lock.json
npm install

# 或者手动修复权限
chmod +x node_modules/.bin/*

问题5:sudo 权限要求密码

现象:

bash
remote: sudo: a terminal is required to read the password
remote: sudo: a password is required

原因分析:

  • Git Hook 环境中无法交互式输入密码
  • sudo systemctl 需要特殊权限配置

解决方案:

bash
# 配置 nginx 相关命令的免密 sudo
sudo visudo -f /etc/sudoers.d/webnote-nginx

# 添加内容:
webnote ALL=(ALL) NOPASSWD: /bin/systemctl reload nginx, /bin/systemctl restart nginx, /bin/systemctl status nginx

7. 最佳实践总结

7.1 为什么显式使用 0.0.0.0

在Nginx配置中使用 listen 0.0.0.0:8080 而不是 listen 8080

优势:

  • 更加明确,避免默认行为的歧义
  • 与 VitePress --host 0.0.0.0 保持一致
  • 便于理解和调试

7.2 权限设置策略

bash
# 目录权限(允许遍历)
chmod 755 /home/webnote
chmod 755 /home/webnote/webnote
chmod 755 /home/webnote/webnote/build

# 文件权限(只读)
chmod -R 644 /home/webnote/webnote/build/*

# 确保目录可执行
find /home/webnote/webnote/build -type d -exec chmod 755 {} \;

7.3 UFW 防火墙考虑

要点:

  • 云服务器通常已有云防火墙保护
  • UFW 是可选的额外安全层
  • 如启用 UFW,务必先允许 SSH 端口
bash
# 如果需要启用 UFW
sudo ufw allow 22    # SSH - 重要!先允许
sudo ufw allow 8080  # 网站端口
sudo ufw enable       # 最后启用

第四阶段:测试和验证

8. 完整测试流程

8.1 本地推送测试

bash
# 在本地项目目录
echo "测试自动部署 - $(date)" >> README.md
git add .
git commit -m "Test: 验证自动部署系统"
git push origin master

期望输出:

bash
remote: === Starting Auto Deployment ===
remote: Detected node_modules exists, skipping npm install
remote: 2. Building project...
remote: 3. Backing up current version...
remote: 4. Updating build files...
remote: 4.1 Setting correct permissions...
remote: 5. Reloading Nginx...
remote: Nginx reloaded successfully
remote: === Deployment Completed ===
remote: 🌐 Website available at: http://43.159.60.248:8080

8.2 服务状态检查

bash
# 检查 Nginx 状态
sudo systemctl status nginx

# 检查端口监听
sudo netstat -tlnp | grep 8080

# 本地访问测试
curl -I http://localhost:8080

# 查看部署日志
tail -10 ~/webnote/logs/deploy.log

8.3 外网访问验证

在浏览器中访问:http://43.159.60.248:8080

第五阶段:监控和维护工具

9. 实用脚本集合

9.1 部署状态监控

bash
nano ~/webnote/deploy-monitor.sh
bash
#!/bin/bash
echo "=== VitePress Deployment Status Monitor ==="

echo "Last deployment time:"
tail -1 ~/webnote/logs/deploy.log

echo -e "\n=== Git Repository Status ==="
cd ~/webnote/source/WebNote
echo "Current branch: $(git branch --show-current)"
echo "Latest commit: $(git log -1 --oneline)"

echo -e "\n=== Build Files Status ==="
if [ -d "~/webnote/build" ] && [ "$(ls -A ~/webnote/build)" ]; then
    echo "Build files exist, last modified:"
    ls -la ~/webnote/build/index.html | awk '{print $6" "$7" "$8}'
else
    echo "Build files do not exist or are empty"
fi

echo -e "\n=== Website Service Status ==="
curl -s -o /dev/null -w "HTTP Status: %{http_code}\n" http://localhost:8080 || echo "Website is not accessible"

echo -e "\n=== System Resource Usage ==="
echo "Disk usage:"
df -h /home/webnote | grep -v Filesystem
echo "Memory usage:"
free -h | grep Mem

9.2 手动部署脚本(备用)

bash
nano ~/webnote/manual-deploy.sh
bash
#!/bin/bash
echo "Starting manual deployment..."

cd ~/webnote/source/WebNote

echo "1. Pulling latest code..."
git pull origin master

echo "2. Installing/updating dependencies..."
npm install

echo "3. Building project..."
npm run docs:build

echo "4. Backing up current version..."
if [ -d "~/webnote/build" ] && [ "$(ls -A ~/webnote/build)" ]; then
    cp -r ~/webnote/build ~/webnote/build.bak.$(date +%Y%m%d_%H%M%S)
fi

echo "5. Updating build files..."
rm -rf ~/webnote/build/*
cp -r docs/.vitepress/dist/* ~/webnote/build/

echo "6. Setting permissions..."
chmod 755 /home/webnote /home/webnote/webnote /home/webnote/webnote/build
chmod -R 644 ~/webnote/build/*
find ~/webnote/build -type d -exec chmod 755 {} \;

echo "7. Reloading Nginx..."
sudo systemctl reload nginx

echo "Manual deployment completed! Access at: http://43.159.60.248:8080"

9.3 设置脚本权限

bash
chmod +x ~/webnote/deploy-monitor.sh
chmod +x ~/webnote/manual-deploy.sh

10. 开发服务器配置(可选)

如需实时预览功能:

bash
nano ~/webnote/dev-server.sh
bash
#!/bin/bash
cd ~/webnote/source/WebNote

echo "=== Starting VitePress Development Server ==="
echo "Production Environment: http://43.159.60.248:8080"
echo "Development Preview: http://43.159.60.248:3000"
echo "Press Ctrl+C to stop the server"
echo ""

npm run docs:dev -- --host 0.0.0.0 --port 3000

疑难问题诊断工具

11. 综合诊断脚本

当遇到问题时,使用此脚本进行全面诊断:

bash
nano ~/webnote/full-diagnosis.sh
bash
#!/bin/bash
echo "=== Complete System Diagnosis ==="

echo "1. System Info:"
uname -a
echo "Node.js: $(node --version)"
echo "NPM: $(npm --version)"

echo -e "\n2. Network Status:"
echo "Listening ports:"
sudo netstat -tlnp | grep -E "(8080|3000|22)"

echo -e "\n3. Nginx Status:"
sudo systemctl status nginx --no-pager
sudo nginx -t

echo -e "\n4. File Structure:"
echo "Build directory:"
ls -la ~/webnote/build/ | head -5
echo "Source directory:"
ls -la ~/webnote/source/WebNote/ | head -5

echo -e "\n5. Permissions Check:"
echo "Directory permissions:"
ls -ld /home/webnote /home/webnote/webnote /home/webnote/webnote/build
echo "www-data access test:"
sudo -u www-data test -r /home/webnote/webnote/build/index.html && echo "✅ Can read" || echo "❌ Cannot read"

echo -e "\n6. Git Status:"
cd ~/webnote/source/WebNote
git status --porcelain
echo "Latest commit: $(git log -1 --oneline)"

echo -e "\n7. Recent Logs:"
echo "--- Deploy Log ---"
tail -5 ~/webnote/logs/deploy.log 2>/dev/null || echo "No deploy log"
echo "--- Nginx Error Log ---"
sudo tail -5 /var/log/nginx/error.log

echo -e "\n8. Service Test:"
curl -s -I http://localhost:8080 | head -1

echo -e "\n=== Diagnosis Complete ==="
bash
chmod +x ~/webnote/full-diagnosis.sh

PM2 进程管理与监控

PM2 是一个强大的进程管理工具,适用于 Node.js 应用。虽然 VitePress 在生产环境使用静态文件部署,但 PM2 在开发环境和扩展功能时非常有用。

12. PM2 基础配置

12.1 创建 PM2 配置文件

bash
nano ~/webnote/ecosystem.config.js

添加以下内容:

javascript
module.exports = {
  apps: [
    {
      name: "webnote-dev",
      script: "npm",
      args: "run docs:dev",
      cwd: "/home/webnote/webnote/source/WebNote",
      env: {
        NODE_ENV: "development",
      },
      watch: false,
      instances: 1,
      autorestart: true,
      max_memory_restart: "300M",
      log_date_format: "YYYY-MM-DD HH:mm:ss",
      out_file: "/home/webnote/webnote/logs/webnote-dev-out.log",
      error_file: "/home/webnote/webnote/logs/webnote-dev-error.log",
    }
  ]
};

12.2 使用 PM2 启动开发服务器

bash
# 启动开发服务器
pm2 start ~/webnote/ecosystem.config.js

# 查看运行状态
pm2 status

# 查看日志
pm2 logs webnote-dev

# 设置开机自启
pm2 save
pm2 startup
# 执行上述命令后的指示

13. PM2 进程管理工具箱

13.1 创建管理脚本

bash
nano ~/webnote/pm2-manage.sh

添加以下内容:

bash
#!/bin/bash
# PM2 服务管理脚本

ACTION=$1
APP_NAME="webnote-dev"
CONFIG_PATH="/home/webnote/webnote/ecosystem.config.js"

function show_usage {
  echo "用法: $0 [start|stop|restart|status|logs|monitor]"
  echo ""
  echo "选项:"
  echo "  start   - 启动 VitePress 开发服务器"
  echo "  stop    - 停止服务"
  echo "  restart - 重启服务"
  echo "  status  - 显示服务状态"
  echo "  logs    - 显示服务日志"
  echo "  monitor - 打开 PM2 监控面板"
}

case "$ACTION" in
  start)
    echo "启动 VitePress 开发服务器..."
    pm2 start $CONFIG_PATH
    echo "服务已启动,访问: http://43.159.60.248:3000"
    ;;
  stop)
    echo "停止服务..."
    pm2 stop $APP_NAME
    ;;
  restart)
    echo "重启服务..."
    pm2 restart $APP_NAME
    ;;
  status)
    echo "服务状态:"
    pm2 status $APP_NAME
    ;;
  logs)
    echo "显示服务日志 (Ctrl+C 退出):"
    pm2 logs $APP_NAME
    ;;
  monitor)
    echo "启动 PM2 监控面板 (Ctrl+C 退出):"
    pm2 monit
    ;;
  *)
    show_usage
    ;;
esac

设置执行权限:

bash
chmod +x ~/webnote/pm2-manage.sh

14. 高级 PM2 使用案例

14.1 配置集群模式(适用于API服务)

如果您计划为VitePress添加自定义API服务(如搜索功能),可以使用PM2的集群模式:

bash
nano ~/webnote/api-ecosystem.config.js

添加以下内容:

javascript
module.exports = {
  apps: [
    {
      name: "webnote-api",
      script: "/home/webnote/webnote/source/WebNote/api/server.js",
      cwd: "/home/webnote/webnote/source/WebNote",
      env: {
        NODE_ENV: "production",
        PORT: 3001
      },
      instances: "max", // 使用所有可用CPU核心
      exec_mode: "cluster",
      autorestart: true,
      watch: false,
      max_memory_restart: "300M",
      log_date_format: "YYYY-MM-DD HH:mm:ss",
      out_file: "/home/webnote/webnote/logs/api-out.log",
      error_file: "/home/webnote/webnote/logs/api-error.log",
    }
  ]
};

启动API服务:

bash
pm2 start ~/webnote/api-ecosystem.config.js

14.2 性能监控

bash
# 实时监控仪表板
pm2 monit

# 检查单个应用详情
pm2 show webnote-dev

# 查看所有应用状态
pm2 status

# 使用web界面监控(需要安装pm2-web)
pm2 install pm2-web
# 访问 http://43.159.60.248:9615

14.3 日志管理

bash
# 查看实时日志
pm2 logs

# 查看特定应用的日志
pm2 logs webnote-dev

# 清空日志
pm2 flush

# 重载日志(在配置logrotate后使用)
pm2 reloadLogs

14.4 配置日志轮转

PM2不自带日志轮转功能,需要配合logrotate使用:

bash
sudo nano /etc/logrotate.d/pm2-webnote

添加以下内容:

/home/webnote/webnote/logs/*.log {
  daily
  missingok
  rotate 7
  compress
  delaycompress
  notifempty
  create 0640 webnote webnote
  postrotate
    su - webnote -c "pm2 reloadLogs" > /dev/null 2>&1 || true
  endscript
}

15. PM2 与 Nginx 配合使用

对于需要将API服务与静态文件结合的场景,可以配置Nginx反向代理:

bash
sudo nano /etc/nginx/sites-available/webnote

修改或添加以下内容:

nginx
server {
    listen 8080;
    server_name 43.159.60.248 _;

    # 静态文件部分不变
    root /home/webnote/webnote/build;
    index index.html;

    # 新增API反向代理配置
    location /api/ {
        proxy_pass http://localhost:3001/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    # 其他配置保持不变...
}

重新加载Nginx配置:

bash
sudo nginx -t
sudo systemctl reload nginx

16. PM2 常见问题排查

16.1 内存泄漏问题

如果观察到内存使用量持续增长:

bash
# 设置自动重启策略
pm2 update
pm2 restart webnote-dev --max-memory-restart 300M

16.2 启动失败问题

bash
# 查看详细错误
pm2 logs webnote-dev --lines 100

# 检查服务器资源
free -h
df -h

16.3 CPU使用率过高

bash
# 生成CPU分析报告
pm2 start app.js --node-args="--prof"
# 使用一段时间后
pm2 stop app
# 分析生成的日志文件
node --prof-process isolate-*.log > profile.txt

PM2 的价值与适用场景

虽然 VitePress 的生产环境是静态部署,但引入 PM2 进程管理器可以带来以下优势:

  1. 开发服务器管理:让 VitePress 开发服务器持久运行,SSH 断开后仍可访问

  2. 系统健壮性:通过自动重启功能,确保服务可靠运行

  3. 资源监控:实时监控内存、CPU 使用情况,及早发现潜在问题

  4. 扩展能力:为网站添加自定义 API 服务(如搜索、编辑功能)时,使用 PM2 的集群模式提升性能

  5. 日志集中管理:统一的日志系统,简化问题排查

  6. 系统集成:开机自启动,确保服务器重启后服务自动恢复

PM2 的使用不仅仅适用于生产环境,在开发和测试阶段同样有价值,特别是在远程服务器上进行协作开发时。

总结:完整部署系统

🎯 系统特点

自动化程度:

  • ✅ Git 推送自动部署
  • ✅ 智能依赖管理
  • ✅ 自动权限设置
  • ✅ 完整日志记录

稳定性保障:

  • ✅ 备份机制
  • ✅ 错误处理
  • ✅ 监控脚本
  • ✅ 手动恢复方案

扩展能力:

  • ✅ 开发预览服务器
  • ✅ 多环境支持
  • ✅ API 扩展准备

🚀 日常工作流

bash
# 本地开发流程
cd d:\github_vs\WebNote
# 编辑文档...
git add .
git commit -m "更新文档内容"
git push origin master

# 服务器自动执行全套部署流程
# 访问 http://43.159.60.248:8080 查看更新

📊 维护命令

bash
# 查看部署状态
~/webnote/deploy-monitor.sh

# 查看系统状态
~/webnote/full-diagnosis.sh

# 手动部署(紧急情况)
~/webnote/manual-deploy.sh

# 查看实时日志
tail -f ~/webnote/logs/deploy.log

💡 关键经验总结

  1. 权限配置是核心:Linux 目录权限设置直接影响服务可用性
  2. 显式配置更可靠:明确指定 0.0.0.0 避免网络配置歧义
  3. 智能检测提高效率:自动判断是否需要 npm install
  4. 完整错误处理:预见问题并提供解决方案
  5. 监控和日志必不可少:便于问题诊断和系统维护

这套系统已经过实际测试,能够稳定支持 VitePress 网站的生产环境部署和日常维护。


🌐 部署完成!访问地址:http://43.159.60.248:8080

目录

  1. 总结:完整部署系统
  2. 更新日志

更新日志

2023年6月10日

  • 初始版本:完成基本部署指南文档
  • 添加自动化部署钩子脚本
  • 添加 Nginx 配置指南

2023年8月15日

  • 补充常见问题解决方案
  • 改进钩子脚本,增强错误处理
  • 添加权限问题详细排查步骤

2023年10月1日

  • 添加备份与恢复章节
  • 新增自动备份脚本和恢复流程
  • 完善数据迁移策略

2023年12月18日

  • 添加 HTTPS 配置完整教程
  • 增加 SSL 安全性优化建议
  • 新增 SSL 故障排除指南

PM2 进程管理与监控

PM2 是一个强大的进程管理工具,适用于 Node.js 应用。虽然 VitePress 在生产环境使用静态文件部署,但 PM2 在开发环境和扩展功能时非常有用。

12. PM2 基础配置

12.1 创建 PM2 配置文件

bash
nano ~/webnote/ecosystem.config.js

添加以下内容:

javascript
module.exports = {
  apps: [
    {
      name: "webnote-dev",
      script: "npm",
      args: "run docs:dev",
      cwd: "/home/webnote/webnote/source/WebNote",
      env: {
        NODE_ENV: "development",
      },
      watch: false,
      instances: 1,
      autorestart: true,
      max_memory_restart: "300M",
      log_date_format: "YYYY-MM-DD HH:mm:ss",
      out_file: "/home/webnote/webnote/logs/webnote-dev-out.log",
      error_file: "/home/webnote/webnote/logs/webnote-dev-error.log",
    }
  ]
};

12.2 使用 PM2 启动开发服务器

bash
# 启动开发服务器
pm2 start ~/webnote/ecosystem.config.js

# 查看运行状态
pm2 status

# 查看日志
pm2 logs webnote-dev

# 设置开机自启
pm2 save
pm2 startup
# 执行上述命令后的指示

13. PM2 进程管理工具箱

13.1 创建管理脚本

bash
nano ~/webnote/pm2-manage.sh

添加以下内容:

bash
#!/bin/bash
# PM2 服务管理脚本

ACTION=$1
APP_NAME="webnote-dev"
CONFIG_PATH="/home/webnote/webnote/ecosystem.config.js"

function show_usage {
  echo "用法: $0 [start|stop|restart|status|logs|monitor]"
  echo ""
  echo "选项:"
  echo "  start   - 启动 VitePress 开发服务器"
  echo "  stop    - 停止服务"
  echo "  restart - 重启服务"
  echo "  status  - 显示服务状态"
  echo "  logs    - 显示服务日志"
  echo "  monitor - 打开 PM2 监控面板"
}

case "$ACTION" in
  start)
    echo "启动 VitePress 开发服务器..."
    pm2 start $CONFIG_PATH
    echo "服务已启动,访问: http://43.159.60.248:3000"
    ;;
  stop)
    echo "停止服务..."
    pm2 stop $APP_NAME
    ;;
  restart)
    echo "重启服务..."
    pm2 restart $APP_NAME
    ;;
  status)
    echo "服务状态:"
    pm2 status $APP_NAME
    ;;
  logs)
    echo "显示服务日志 (Ctrl+C 退出):"
    pm2 logs $APP_NAME
    ;;
  monitor)
    echo "启动 PM2 监控面板 (Ctrl+C 退出):"
    pm2 monit
    ;;
  *)
    show_usage
    ;;
esac

设置执行权限:

bash
chmod +x ~/webnote/pm2-manage.sh

14. 高级 PM2 使用案例

14.1 配置集群模式(适用于API服务)

如果您计划为VitePress添加自定义API服务(如搜索功能),可以使用PM2的集群模式:

bash
nano ~/webnote/api-ecosystem.config.js

添加以下内容:

javascript
module.exports = {
  apps: [
    {
      name: "webnote-api",
      script: "/home/webnote/webnote/source/WebNote/api/server.js",
      cwd: "/home/webnote/webnote/source/WebNote",
      env: {
        NODE_ENV: "production",
        PORT: 3001
      },
      instances: "max", // 使用所有可用CPU核心
      exec_mode: "cluster",
      autorestart: true,
      watch: false,
      max_memory_restart: "300M",
      log_date_format: "YYYY-MM-DD HH:mm:ss",
      out_file: "/home/webnote/webnote/logs/api-out.log",
      error_file: "/home/webnote/webnote/logs/api-error.log",
    }
  ]
};

启动API服务:

bash
pm2 start ~/webnote/api-ecosystem.config.js

14.2 性能监控

bash
# 实时监控仪表板
pm2 monit

# 检查单个应用详情
pm2 show webnote-dev

# 查看所有应用状态
pm2 status

# 使用web界面监控(需要安装pm2-web)
pm2 install pm2-web
# 访问 http://43.159.60.248:9615

14.3 日志管理

bash
# 查看实时日志
pm2 logs

# 查看特定应用的日志
pm2 logs webnote-dev

# 清空日志
pm2 flush

# 重载日志(在配置logrotate后使用)
pm2 reloadLogs

14.4 配置日志轮转

PM2不自带日志轮转功能,需要配合logrotate使用:

bash
sudo nano /etc/logrotate.d/pm2-webnote

添加以下内容:

/home/webnote/webnote/logs/*.log {
  daily
  missingok
  rotate 7
  compress
  delaycompress
  notifempty
  create 0640 webnote webnote
  postrotate
    su - webnote -c "pm2 reloadLogs" > /dev/null 2>&1 || true
  endscript
}

15. PM2 与 Nginx 配合使用

对于需要将API服务与静态文件结合的场景,可以配置Nginx反向代理:

bash
sudo nano /etc/nginx/sites-available/webnote

修改或添加以下内容:

nginx
server {
    listen 8080;
    server_name 43.159.60.248 _;

    # 静态文件部分不变
    root /home/webnote/webnote/build;
    index index.html;

    # 新增API反向代理配置
    location /api/ {
        proxy_pass http://localhost:3001/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    # 其他配置保持不变...
}

重新加载Nginx配置:

bash
sudo nginx -t
sudo systemctl reload nginx

16. PM2 常见问题排查

16.1 内存泄漏问题

如果观察到内存使用量持续增长:

bash
# 设置自动重启策略
pm2 update
pm2 restart webnote-dev --max-memory-restart 300M

16.2 启动失败问题

bash
# 查看详细错误
pm2 logs webnote-dev --lines 100

# 检查服务器资源
free -h
df -h

16.3 CPU使用率过高

bash
# 生成CPU分析报告
pm2 start app.js --node-args="--prof"
# 使用一段时间后
pm2 stop app
# 分析生成的日志文件
node --prof-process isolate-*.log > profile.txt

PM2 的价值与适用场景

虽然 VitePress 的生产环境是静态部署,但引入 PM2 进程管理器可以带来以下优势:

  1. 开发服务器管理:让 VitePress 开发服务器持久运行,SSH 断开后仍可访问

  2. 系统健壮性:通过自动重启功能,确保服务可靠运行

  3. 资源监控:实时监控内存、CPU 使用情况,及早发现潜在问题

  4. 扩展能力:为网站添加自定义 API 服务(如搜索、编辑功能)时,使用 PM2 的集群模式提升性能

  5. 日志集中管理:统一的日志系统,简化问题排查

  6. 系统集成:开机自启动,确保服务器重启后服务自动恢复

PM2 的使用不仅仅适用于生产环境,在开发和测试阶段同样有价值,特别是在远程服务器上进行协作开发时。

总结:完整部署系统

🎯 系统特点

自动化程度:

  • ✅ Git 推送自动部署
  • ✅ 智能依赖管理
  • ✅ 自动权限设置
  • ✅ 完整日志记录

稳定性保障:

  • ✅ 备份机制
  • ✅ 错误处理
  • ✅ 监控脚本
  • ✅ 手动恢复方案

扩展能力:

  • ✅ 开发预览服务器
  • ✅ 多环境支持
  • ✅ API 扩展准备

🚀 日常工作流

bash
# 本地开发流程
cd d:\github_vs\WebNote
# 编辑文档...
git add .
git commit -m "更新文档内容"
git push origin master

# 服务器自动执行全套部署流程
# 访问 http://43.159.60.248:8080 查看更新

📊 维护命令

bash
# 查看部署状态
~/webnote/deploy-monitor.sh

# 查看系统状态
~/webnote/full-diagnosis.sh

# 手动部署(紧急情况)
~/webnote/manual-deploy.sh

# 查看实时日志
tail -f ~/webnote/logs/deploy.log

💡 关键经验总结

  1. 权限配置是核心:Linux 目录权限设置直接影响服务可用性
  2. 显式配置更可靠:明确指定 0.0.0.0 避免网络配置歧义
  3. 智能检测提高效率:自动判断是否需要 npm install
  4. 完整错误处理:预见问题并提供解决方案
  5. 监控和日志必不可少:便于问题诊断和系统维护

这套系统已经过实际测试,能够稳定支持 VitePress 网站的生产环境部署和日常维护。


🌐 部署完成!访问地址:http://43.159.60.248:8080

目录

  1. 总结:完整部署系统
  2. 更新日志

更新日志

2023年6月10日

  • 初始版本:完成基本部署指南文档
  • 添加自动化部署钩子脚本
  • 添加 Nginx 配置指南

2023年8月15日

  • 补充常见问题解决方案
  • 改进钩子脚本,增强错误处理
  • 添加权限问题详细排查步骤

2023年10月1日

  • 添加备份与恢复章节
  • 新增自动备份脚本和恢复流程
  • 完善数据迁移策略

2023年12月18日

  • 添加 HTTPS 配置完整教程
  • 增加 SSL 安全性优化建议
  • 新增 SSL 故障排除指南