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 连接服务器
ssh username@43.159.60.248
1.2 创建专用用户
sudo adduser webnote
sudo usermod -aG sudo webnote
su - webnote
1.3 创建目录结构
mkdir -p ~/webnote/{source,build,logs}
cd ~/webnote
2. Node.js 环境配置
2.1 安装 Node.js 20.x LTS
# 移除旧版本
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 安装全局工具
sudo npm install -g pm2
sudo apt install nginx -y
第二阶段:项目部署
3. 代码上传和Git配置
3.1 从本地上传项目
# 在本地 Windows 机器执行
scp -r d:\github_vs\WebNote webnote@43.159.60.248:~/webnote/source/
3.2 在服务器初始化Git
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 创建智能部署脚本
nano ~/webnote/webnote.git/hooks/post-receive
添加以下内容:
#!/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
设置可执行权限:
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
这是由于日志目录权限问题导致的。为了避免此类问题,我们可以使用一个更健壮的钩子脚本版本:
#!/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}"
主要改进点:
- 移除
set -e
:防止因权限错误导致脚本中断 - 安全的日志记录:使用函数处理日志,避免权限问题
- 自动创建目录:确保日志和构建目录存在
- 错误处理:关键步骤添加错误处理逻辑
- 验证部署:增加验证步骤,确认部署成功
- 详细输出:显示更多有用信息,便于调试
如果您曾经遇到权限相关的错误,这个改进版本的脚本可以更稳健地处理这些情况。
5. Nginx 配置
5.1 创建Nginx站点配置
sudo nano /etc/nginx/sites-available/webnote
添加配置:
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 启用站点
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 冲突
现象:
! [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提交历史
- 两个仓库的提交记录不一致导致冲突
解决方案:
# 方案1:强制推送覆盖(推荐,服务器是新环境)
git push -f origin master
# 方案2:合并历史
git pull origin master --allow-unrelated-histories
git push origin master
问题2:Nginx 配置冲突
现象:
nginx: [warn] conflicting server name "43.159.60.248" on 0.0.0.0:8080, ignored
原因分析:
- 多个Nginx配置文件使用相同的 server_name
- 默认站点和自定义站点冲突
解决方案:
# 查找冲突配置
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 内部错误
现象:
curl -I http://localhost:8080
HTTP/1.1 500 Internal Server Error
原因分析:
- www-data 用户无法访问 /home/webnote 目录
- Linux 系统默认用户目录权限限制
解决方案:
# 设置目录权限让 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)
现象:
sh: 1: vitepress: Permission denied
原因分析:
- node_modules 中的可执行文件权限不正确
- Windows 到 Linux 的文件权限映射问题
解决方案:
# 重新安装依赖包获得正确权限
rm -rf node_modules package-lock.json
npm install
# 或者手动修复权限
chmod +x node_modules/.bin/*
问题5:sudo 权限要求密码
现象:
remote: sudo: a terminal is required to read the password
remote: sudo: a password is required
原因分析:
- Git Hook 环境中无法交互式输入密码
- sudo systemctl 需要特殊权限配置
解决方案:
# 配置 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 权限设置策略
# 目录权限(允许遍历)
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 端口
# 如果需要启用 UFW
sudo ufw allow 22 # SSH - 重要!先允许
sudo ufw allow 8080 # 网站端口
sudo ufw enable # 最后启用
第四阶段:测试和验证
8. 完整测试流程
8.1 本地推送测试
# 在本地项目目录
echo "测试自动部署 - $(date)" >> README.md
git add .
git commit -m "Test: 验证自动部署系统"
git push origin master
期望输出:
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 服务状态检查
# 检查 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 部署状态监控
nano ~/webnote/deploy-monitor.sh
#!/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 手动部署脚本(备用)
nano ~/webnote/manual-deploy.sh
#!/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 设置脚本权限
chmod +x ~/webnote/deploy-monitor.sh
chmod +x ~/webnote/manual-deploy.sh
10. 开发服务器配置(可选)
如需实时预览功能:
nano ~/webnote/dev-server.sh
#!/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. 综合诊断脚本
当遇到问题时,使用此脚本进行全面诊断:
nano ~/webnote/full-diagnosis.sh
#!/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 ==="
chmod +x ~/webnote/full-diagnosis.sh
PM2 进程管理与监控
PM2 是一个强大的进程管理工具,适用于 Node.js 应用。虽然 VitePress 在生产环境使用静态文件部署,但 PM2 在开发环境和扩展功能时非常有用。
12. PM2 基础配置
12.1 创建 PM2 配置文件
nano ~/webnote/ecosystem.config.js
添加以下内容:
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 启动开发服务器
# 启动开发服务器
pm2 start ~/webnote/ecosystem.config.js
# 查看运行状态
pm2 status
# 查看日志
pm2 logs webnote-dev
# 设置开机自启
pm2 save
pm2 startup
# 执行上述命令后的指示
13. PM2 进程管理工具箱
13.1 创建管理脚本
nano ~/webnote/pm2-manage.sh
添加以下内容:
#!/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
设置执行权限:
chmod +x ~/webnote/pm2-manage.sh
14. 高级 PM2 使用案例
14.1 配置集群模式(适用于API服务)
如果您计划为VitePress添加自定义API服务(如搜索功能),可以使用PM2的集群模式:
nano ~/webnote/api-ecosystem.config.js
添加以下内容:
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服务:
pm2 start ~/webnote/api-ecosystem.config.js
14.2 性能监控
# 实时监控仪表板
pm2 monit
# 检查单个应用详情
pm2 show webnote-dev
# 查看所有应用状态
pm2 status
# 使用web界面监控(需要安装pm2-web)
pm2 install pm2-web
# 访问 http://43.159.60.248:9615
14.3 日志管理
# 查看实时日志
pm2 logs
# 查看特定应用的日志
pm2 logs webnote-dev
# 清空日志
pm2 flush
# 重载日志(在配置logrotate后使用)
pm2 reloadLogs
14.4 配置日志轮转
PM2不自带日志轮转功能,需要配合logrotate使用:
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反向代理:
sudo nano /etc/nginx/sites-available/webnote
修改或添加以下内容:
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配置:
sudo nginx -t
sudo systemctl reload nginx
16. PM2 常见问题排查
16.1 内存泄漏问题
如果观察到内存使用量持续增长:
# 设置自动重启策略
pm2 update
pm2 restart webnote-dev --max-memory-restart 300M
16.2 启动失败问题
# 查看详细错误
pm2 logs webnote-dev --lines 100
# 检查服务器资源
free -h
df -h
16.3 CPU使用率过高
# 生成CPU分析报告
pm2 start app.js --node-args="--prof"
# 使用一段时间后
pm2 stop app
# 分析生成的日志文件
node --prof-process isolate-*.log > profile.txt
PM2 的价值与适用场景
虽然 VitePress 的生产环境是静态部署,但引入 PM2 进程管理器可以带来以下优势:
开发服务器管理:让 VitePress 开发服务器持久运行,SSH 断开后仍可访问
系统健壮性:通过自动重启功能,确保服务可靠运行
资源监控:实时监控内存、CPU 使用情况,及早发现潜在问题
扩展能力:为网站添加自定义 API 服务(如搜索、编辑功能)时,使用 PM2 的集群模式提升性能
日志集中管理:统一的日志系统,简化问题排查
系统集成:开机自启动,确保服务器重启后服务自动恢复
PM2 的使用不仅仅适用于生产环境,在开发和测试阶段同样有价值,特别是在远程服务器上进行协作开发时。
总结:完整部署系统
🎯 系统特点
自动化程度:
- ✅ Git 推送自动部署
- ✅ 智能依赖管理
- ✅ 自动权限设置
- ✅ 完整日志记录
稳定性保障:
- ✅ 备份机制
- ✅ 错误处理
- ✅ 监控脚本
- ✅ 手动恢复方案
扩展能力:
- ✅ 开发预览服务器
- ✅ 多环境支持
- ✅ API 扩展准备
🚀 日常工作流
# 本地开发流程
cd d:\github_vs\WebNote
# 编辑文档...
git add .
git commit -m "更新文档内容"
git push origin master
# 服务器自动执行全套部署流程
# 访问 http://43.159.60.248:8080 查看更新
📊 维护命令
# 查看部署状态
~/webnote/deploy-monitor.sh
# 查看系统状态
~/webnote/full-diagnosis.sh
# 手动部署(紧急情况)
~/webnote/manual-deploy.sh
# 查看实时日志
tail -f ~/webnote/logs/deploy.log
💡 关键经验总结
- 权限配置是核心:Linux 目录权限设置直接影响服务可用性
- 显式配置更可靠:明确指定 0.0.0.0 避免网络配置歧义
- 智能检测提高效率:自动判断是否需要 npm install
- 完整错误处理:预见问题并提供解决方案
- 监控和日志必不可少:便于问题诊断和系统维护
这套系统已经过实际测试,能够稳定支持 VitePress 网站的生产环境部署和日常维护。
🌐 部署完成!访问地址:http://43.159.60.248:8080
目录
- VitePress 网站部署完整指南
更新日志
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 配置文件
nano ~/webnote/ecosystem.config.js
添加以下内容:
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 启动开发服务器
# 启动开发服务器
pm2 start ~/webnote/ecosystem.config.js
# 查看运行状态
pm2 status
# 查看日志
pm2 logs webnote-dev
# 设置开机自启
pm2 save
pm2 startup
# 执行上述命令后的指示
13. PM2 进程管理工具箱
13.1 创建管理脚本
nano ~/webnote/pm2-manage.sh
添加以下内容:
#!/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
设置执行权限:
chmod +x ~/webnote/pm2-manage.sh
14. 高级 PM2 使用案例
14.1 配置集群模式(适用于API服务)
如果您计划为VitePress添加自定义API服务(如搜索功能),可以使用PM2的集群模式:
nano ~/webnote/api-ecosystem.config.js
添加以下内容:
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服务:
pm2 start ~/webnote/api-ecosystem.config.js
14.2 性能监控
# 实时监控仪表板
pm2 monit
# 检查单个应用详情
pm2 show webnote-dev
# 查看所有应用状态
pm2 status
# 使用web界面监控(需要安装pm2-web)
pm2 install pm2-web
# 访问 http://43.159.60.248:9615
14.3 日志管理
# 查看实时日志
pm2 logs
# 查看特定应用的日志
pm2 logs webnote-dev
# 清空日志
pm2 flush
# 重载日志(在配置logrotate后使用)
pm2 reloadLogs
14.4 配置日志轮转
PM2不自带日志轮转功能,需要配合logrotate使用:
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反向代理:
sudo nano /etc/nginx/sites-available/webnote
修改或添加以下内容:
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配置:
sudo nginx -t
sudo systemctl reload nginx
16. PM2 常见问题排查
16.1 内存泄漏问题
如果观察到内存使用量持续增长:
# 设置自动重启策略
pm2 update
pm2 restart webnote-dev --max-memory-restart 300M
16.2 启动失败问题
# 查看详细错误
pm2 logs webnote-dev --lines 100
# 检查服务器资源
free -h
df -h
16.3 CPU使用率过高
# 生成CPU分析报告
pm2 start app.js --node-args="--prof"
# 使用一段时间后
pm2 stop app
# 分析生成的日志文件
node --prof-process isolate-*.log > profile.txt
PM2 的价值与适用场景
虽然 VitePress 的生产环境是静态部署,但引入 PM2 进程管理器可以带来以下优势:
开发服务器管理:让 VitePress 开发服务器持久运行,SSH 断开后仍可访问
系统健壮性:通过自动重启功能,确保服务可靠运行
资源监控:实时监控内存、CPU 使用情况,及早发现潜在问题
扩展能力:为网站添加自定义 API 服务(如搜索、编辑功能)时,使用 PM2 的集群模式提升性能
日志集中管理:统一的日志系统,简化问题排查
系统集成:开机自启动,确保服务器重启后服务自动恢复
PM2 的使用不仅仅适用于生产环境,在开发和测试阶段同样有价值,特别是在远程服务器上进行协作开发时。
总结:完整部署系统
🎯 系统特点
自动化程度:
- ✅ Git 推送自动部署
- ✅ 智能依赖管理
- ✅ 自动权限设置
- ✅ 完整日志记录
稳定性保障:
- ✅ 备份机制
- ✅ 错误处理
- ✅ 监控脚本
- ✅ 手动恢复方案
扩展能力:
- ✅ 开发预览服务器
- ✅ 多环境支持
- ✅ API 扩展准备
🚀 日常工作流
# 本地开发流程
cd d:\github_vs\WebNote
# 编辑文档...
git add .
git commit -m "更新文档内容"
git push origin master
# 服务器自动执行全套部署流程
# 访问 http://43.159.60.248:8080 查看更新
📊 维护命令
# 查看部署状态
~/webnote/deploy-monitor.sh
# 查看系统状态
~/webnote/full-diagnosis.sh
# 手动部署(紧急情况)
~/webnote/manual-deploy.sh
# 查看实时日志
tail -f ~/webnote/logs/deploy.log
💡 关键经验总结
- 权限配置是核心:Linux 目录权限设置直接影响服务可用性
- 显式配置更可靠:明确指定 0.0.0.0 避免网络配置歧义
- 智能检测提高效率:自动判断是否需要 npm install
- 完整错误处理:预见问题并提供解决方案
- 监控和日志必不可少:便于问题诊断和系统维护
这套系统已经过实际测试,能够稳定支持 VitePress 网站的生产环境部署和日常维护。
🌐 部署完成!访问地址:http://43.159.60.248:8080
目录
- VitePress 网站部署完整指南
更新日志
2023年6月10日
- 初始版本:完成基本部署指南文档
- 添加自动化部署钩子脚本
- 添加 Nginx 配置指南
2023年8月15日
- 补充常见问题解决方案
- 改进钩子脚本,增强错误处理
- 添加权限问题详细排查步骤
2023年10月1日
- 添加备份与恢复章节
- 新增自动备份脚本和恢复流程
- 完善数据迁移策略
2023年12月18日
- 添加 HTTPS 配置完整教程
- 增加 SSL 安全性优化建议
- 新增 SSL 故障排除指南