懒惰是第一生产力,本篇文章关于项目自动化部署,告别手动打包,上传至终端等等操作
作为一名前端开发者,你是否也经历过这样的场景:
每次上线都要重复这"四大步",虽然熟练了,但总归是机械劳动。如果一天上线好几次,时间就被这些重复操作吃掉了。
因为代码存储在Github,所以使用Github Actions实现自动部署
| 工具 | 用途 |
|---|---|
| GitHub Actions | CI/CD 自动化平台 |
| Nuxt 3 | 前端框架 |
| 阿里云 ECS | 服务器运行环境 |
| PM2 | Node.js 进程管理 |
| SSH/SCP | 远程连接与文件传输 |
简单说,GitHub Actions 是 GitHub 内置的 CI/CD 工具。当你的代码仓库发生特定事件(如 push、PR 合并)时,它会在云端的虚拟机上自动执行你预设的任务。
你可以把它理解为一个"机器人助手":
整个过程完全自动化,无需人工干预。
关于服务器的某些配置在此就不再赘述,安装pm2,创建项目目录等等
为了避免将服务器密码等敏感信息写在代码中,将它们存储在 GitHub Secrets 中。
| Secret Name | 示例值 | 说明 |
|---|---|---|
HOST | 1.2.3.4 | 服务器公网 IP |
USERNAME | root | SSH 登录用户名 |
PASSWORD | ******** | SSH 登录密码 |
在项目根目录下创建 .github/workflows/deploy.yml:
该配置以nuxt技术栈项目为例,不同技术栈会有些许不同
# ============================================
# GitHub Actions 工作流配置文件
# 作用:当代码推送到 main 分支时,自动构建并部署 Nuxt 项目到阿里云 ECS
# ============================================
# 工作流名称(显示在 GitHub Actions 页面)
name: Deploy Nuxt to Aliyun ECS
# ============================================
# 触发条件配置
# ============================================
on:
push:
branches: [ main ] # 只有推送到 main 分支时才触发
# ============================================
# 工作任务定义
# ============================================
jobs:
# 任务名称:构建并部署
build-and-deploy:
# 运行环境:使用 GitHub 提供的 Ubuntu 虚拟机
runs-on: ubuntu-latest
# 指定环境(用于读取该环境下的 Secrets)
environment: prod
# ============================================
# 执行步骤(按顺序从上到下执行)
# ============================================
steps:
# ---------- 步骤 1:拉取代码 ----------
- name: Checkout code
uses: actions/checkout@v4
# 作用:将 GitHub 仓库的代码下载到虚拟机上
# @v4 是版本号,表示使用第 4 个大版本
# ---------- 步骤 2:安装 Node.js ----------
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18' # 指定 Node.js 版本(改成你项目实际使用的版本)
cache: 'npm' # 缓存 node_modules,加速后续构建
# 作用:在虚拟机上安装 Node.js 环境
# 为什么需要:虚拟机是干净的,没有 Node.js
# ---------- 步骤 3:安装项目依赖 ----------
- name: Install dependencies
run: npm ci
# 作用:安装 package.json 中声明的所有依赖
# npm ci 特点:
# - 比 npm install 更快
# - 严格按照 package-lock.json 安装,保证版本一致性
# - 专门为 CI/CD 环境设计
# 注意:这只是在 GitHub 虚拟机上安装依赖用于构建!
# 服务器上不需要再安装,因为 .output 已自包含
# ---------- 步骤 4:构建 Nuxt 项目 ----------
- name: Build application
run: npm run build
# 作用:执行 package.json 中的 build 命令
# 对于 Nuxt 3:生成 .output 目录(自包含的构建产物)
# 对于 Nuxt 2:生成 .nuxt 目录
#
# ⚠️ 重要:Nuxt 3 的 .output 目录特点:
# - 包含了所有编译后的代码
# - 包含了运行时需要的所有依赖
# - 是"自包含"的,不需要在服务器上再执行 npm install
# - 直接可以用 node .output/server/index.mjs 启动
# ---------- 步骤 5:打包构建产物 ----------
- name: Package build artifacts
run: tar -czf release.tgz .output
# 作用:将 .output 文件夹压缩成 .tgz 文件
# 为什么压缩:
# - 单个文件传输比成千上万个小文件快得多
# - 减少网络传输时间
# 参数说明:
# - c:创建压缩包 (create)
# - z:使用 gzip 压缩
# - f:指定文件名 (file)
#
# ⚠️ 注意:只打包 .output,不打包 node_modules
# 因为 .output 已经自包含,不需要服务器端安装依赖
# ---------- 步骤 6:部署到阿里云 ECS ----------
- name: Deploy to Aliyun ECS
# 从 GitHub Secrets 中读取服务器连接信息
env:
HOST: ${{ secrets.HOST }} # 服务器公网 IP
USERNAME: ${{ secrets.USERNAME }} # SSH 登录用户名
PASSWORD: ${{ secrets.PASSWORD }} # SSH 登录密码
run: |
# --------------------------------------------
# 6.1 安装 sshpass 工具
# --------------------------------------------
sudo apt-get update
sudo apt-get install -y sshpass
# sshpass 作用:在命令行中自动输入 SSH 密码
# 为什么需要:scp 和 ssh 命令本身不支持 -p 密码参数
# 没有 sshpass 的话,每次都需要手动输入密码
# 在 CI/CD 中无法手动输入,所以需要自动认证
# --------------------------------------------
# 6.2 上传压缩包到服务器
# --------------------------------------------
echo "=== 1. 上传压缩包到服务器 ==="
sshpass -p "$PASSWORD" scp \
-o StrictHostKeyChecking=no \
release.tgz $USERNAME@$HOST:/nuxt/project/
# 命令拆解:
# sshpass -p "$PASSWORD" :用密码自动认证
# scp :Secure Copy,基于 SSH 的文件传输
# -o StrictHostKeyChecking=no:跳过"是否信任此主机"的询问
# release.tgz :要上传的本地文件
# root@1.2.3.4:/nuxt/project/:目标位置
#
# ⚠️ 路径说明:
# /nuxt/project/ 是你的项目部署目录
# 如果路径不同,修改成你服务器上的实际路径
# --------------------------------------------
# 6.3 在服务器上执行部署命令
# --------------------------------------------
echo "=== 2. 执行部署命令 ==="
sshpass -p "$PASSWORD" ssh \
-o StrictHostKeyChecking=no \
$USERNAME@$HOST << 'EOF'
# 上面的命令通过 SSH 连接到服务器
# << 'EOF' 表示之后的内容都在服务器上执行,直到遇到 EOF
# ---------- 错误处理 ----------
set -e
# 作用:任何命令失败(返回非 0 值),脚本立即退出
# 防止"部分失败"导致部署不完整
# ---------- 进入部署目录 ----------
cd /nuxt/project
# 切换到项目部署目录
# ⚠️ 如果路径不同,请修改
# ---------- 显示当前状态 ----------
echo "📂 当前目录: $(pwd)"
echo "📦 检查压缩包:"
ls -lh release.tgz
# 确认压缩包已成功上传
# ---------- 备份旧版本 ----------
echo "📦 备份旧版本..."
if [ -d ".output" ]; then
mv .output .output.backup.$(date +%Y%m%d_%H%M%S)
fi
# 作用:如果存在旧版本,先备份
# 为什么备份:如果新版本有问题,可以快速回滚
# 备份命名:.output.backup.20260817_120000(带时间戳)
# ---------- 解压新版本 ----------
echo "📦 解压新版本..."
tar -xzf release.tgz
# 解压压缩包,生成 .output 目录
#
# ⚠️ Nuxt 3 特别说明:
# .output 目录是"自包含"的
# 不需要执行 npm install
# 不需要执行 npm run build
# 直接就可以运行
# ---------- 验证解压结果 ----------
echo "✅ 验证解压结果:"
ls -la .output/server/index.mjs
# 检查关键入口文件是否存在
# 如果文件不存在,ls 会报错,set -e 会停止执行
# ---------- 清理压缩包 ----------
echo "🧹 清理压缩包..."
rm -f release.tgz
# 删除压缩包,释放磁盘空间
# ---------- 重启 PM2 服务 ----------
echo "🔄 重启 PM2..."
if pm2 list | grep -q "nuxt-blog"; then
# 如果 PM2 中已有该应用,则重启
pm2 restart nuxt-blog
else
# 如果是首次部署,PM2 中还没有该应用,则启动
pm2 start .output/server/index.mjs --name nuxt-blog
fi
# pm2 list :列出所有 PM2 应用
# grep -q "nuxt-blog":静默搜索(不输出结果,只返回成功/失败)
#
# 为什么需要判断:
# - 首次部署时,PM2 中没有该应用
# - restart 会报错 "Process not found"
# - 所以先用 start,后续用 restart
# ---------- 保存 PM2 配置 ----------
pm2 save
# 作用:保存当前 PM2 进程列表
# 效果:服务器重启后,PM2 会自动恢复这些进程
# 相当于"开机自启"配置
# ---------- 显示最终状态 ----------
pm2 status
# 显示所有 PM2 应用的运行状态
# 确认 nuxt-blog 是 online 状态
EOF
# EOF 结束标记:以上都是在服务器上执行的命令
# --------------------------------------------
# 6.4 部署完成提示
# --------------------------------------------
echo "✅ 部署完成!"当你将代码推送到main分支时,一切自动发生
上述为大致总结,个人项目通过此操作可实现自动化部署~
布莱克的个人微信小程序

© 2025 - 2026 Black Blog. All rights reserved. | 豫ICP备2025153558号-1
© 2025 Black Blog. All rights reserved.
豫ICP备2025153558号-1
