当前位置: 首页 > ai >正文

使用CI/CD部署项目(前端Nextjs)

写在前面:在github上使用CI/CD部署Nextjs项目,具体配置可以按照自己的实际的修改

这是我的项目配置,仅供参考
在这里插入图片描述
后端项目可以参考:使用CI/CD部署后端项目

正文开始

项目名(PROJECT_NAME)- CI/CD 部署指南(GitHub Actions + SSH + PM2)

本项目已内置基于 GitHub Actions 的 CI/CD。它会在 main 分支有变更或手动触发时:

  • 安装依赖并构建 Next.js 产物
  • 通过 SCP 将构建产物上传至服务器指定目录
  • 通过 SSH 调用 PM2 平滑重载运行中的服务

1. 文件位置

  • 工作流文件(部署文件示例已经放到文末):.github/workflows/deploy.yml

2. 前置条件

  • 服务器已安装 Node.js 18.x 与 npm(与工作流一致)
  • 服务器已安装 PM2:npm i -g pm2
  • 服务器部署目录存在且对 SSH 用户可写,例如:/var/www/PROJECT_NAME

3. 仓库 Secrets 配置

在 GitHub → 仓库 → Settings → Secrets and variables → Actions 中添加:

必填

  • SSH_HOST:服务器 IP/域名
  • SSH_USER:SSH 用户名
  • SSH_PORT:SSH 端口(如 22)
  • SSH_PASSWORD:SSH 登录密码(如改用密钥见文末)
  • REMOTE_PATH:服务器部署根目录(例如 /var/www/PROJECT_NAME

可选

  • ENV_FILE_CONTENTS:用于生成 .env.production 的完整文本。例如:
    NEXT_PUBLIC_API_URL=https://api.your-domain.com
    NEXT_PUBLIC_LANGUAGE=en
    NEXT_PUBLIC_WALLETCONNECT_ID=xxxxxxx
    

说明

  • 工作流会在“构建前”把 ENV_FILE_CONTENTS 写为 .env.production,确保 NEXT_PUBLIC_* 变量参与 Next.js 打包。

4. 服务器目录结构(默认)

工作流会将 release.tar.gz 上传至 REMOTE_PATH 并解压到 REMOTE_PATH/current 下:

REMOTE_PATH/└── current/├── .next/├── public/├── ecosystem.config.js├── package.json├── package-lock.json├── .env.production (可选)└── ...

5. 触发部署

  • 自动:向 main 分支推送代码会自动触发
  • 手动:GitHub → Actions → 选择 CI/CD DeployRun workflow → 选择 main

6. 运行流程概览

  1. Checkout 代码
  2. 使用 Node 18 安装依赖(包含 devDependencies)并构建
  3. 压缩构建产物与必要文件为 release.tar.gz
  4. 通过 SCP 上传到服务器 REMOTE_PATH
  5. 通过 SSH:
    • 解压到 REMOTE_PATH/current
    • 写入 .env.production(如提供)
    • npm ci --omit=dev
    • pm2 startOrReload ecosystem.config.js --env production

7. PM2 常用命令

pm2 ls                       # 查看进程
pm2 logs --lines 100         # 查看日志
pm2 restart <name|id>        # 重启
pm2 stop <name|id>           # 停止
pm2 delete <name|id>         # 删除

8. 回滚思路(简易)

当前流程将产物解压到 current/。若需要回滚,推荐:

  • 在服务器保留历史版本目录(可扩展工作流增加 releases/ 与符号链接),或
  • 临时将上一份稳定包重新上传并覆盖 current/pm2 reload

9. 常见问题与排查

  • 构建期报 Cannot find module 'xxx':确保安装步骤包含 devDependencies(本工作流已处理)。
  • SCP/SSH 失败:检查 SSH_HOST/USER/PORT/PASSWORD 是否正确,服务器防火墙、安全组、端口开放情况。
  • 权限问题:确保 REMOTE_PATHSSH_USER 可写,如需:sudo chown -R <user>:<user> /var/www/PROJECT_NAME
  • 环境变量不生效:确认 ENV_FILE_CONTENTS 已填写,变量名与代码中一致(例如 NEXT_PUBLIC_API_URL)。

10. 切换为 SSH 密钥登录(可选,更安全)

  1. 本地生成密钥:
ssh-keygen -t ed25519 -C "deploy" -N "" -f ~/.ssh/PROJECT_NAME_deploy
  1. ~/.ssh/PROJECT_NAME_deploy.pub 追加到服务器 ~/.ssh/authorized_keys
  2. 在仓库 Secrets 新增:SSH_KEY(粘贴私钥全文),并把工作流中 password: ${{ secrets.SSH_PASSWORD }} 改为 key: ${{ secrets.SSH_KEY }}(scp/ssh 两处)

11. 调整 Node 版本

  • 服务器与工作流默认使用 Node 18。如需升级:同时升级服务器 Node 与工作流的 actions/setup-node 版本号,保持一致。

如需灰度、分环境(staging/prod)或保留多版本回滚,请联系维护者扩展工作流(增加 environmentsreleases 目录策略)。

附:示例工作流(脱敏,含注释与可改项)

# 工作流名称,会显示在 Actions 列表中
name: CI/CD Deployon:# 推送到 main 分支时自动触发(如需改分支,请改这里)push:branches:- main# 允许在 Actions 页面手动触发workflow_dispatch:permissions:contents: readjobs:build-and-deploy:runs-on: ubuntu-latest# Job 级别环境变量:默认生产。构建阶段会临时切到 development 以安装 dev 依赖env:NODE_ENV: productionsteps:# 1) 拉取代码- name: Checkout repositoryuses: actions/checkout@v4# 2) 选择 Node 版本(与服务器一致;可改为 20 等)- name: Use Node.js 18uses: actions/setup-node@v4with:node-version: 18cache: npm# 3) 写入 .env.production(可选)#    值来自仓库 Secret: ENV_FILE_CONTENTS(整段文本,包含多行 KEY=VALUE)- name: Create .env.production from secrets (if provided)env:ENV_FILE_CONTENTS: ${{ secrets.ENV_FILE_CONTENTS }}run: |if [ -n "$ENV_FILE_CONTENTS" ]; thenprintf "%s" "$ENV_FILE_CONTENTS" > .env.productionfi# 4) 安装依赖(包含 devDependencies,避免构建缺包)- name: Install dependencies (with fallback, include dev deps)env:NPM_CONFIG_PRODUCTION: "false"NODE_ENV: developmentrun: |npm ci || npm install --legacy-peer-deps# 5) 构建(生产环境)- name: Buildenv:NODE_ENV: productionrun: npm run build# 6) 仅打包需要的文件(如需额外文件,按需在此补充)- name: Prepare artifact (ship only what is needed)run: |tar -czf release.tar.gz \.next \public \package.json \package-lock.json \next.config.js \ecosystem.config.js \tsconfig.json \postcss.config.js \tailwind.config.js# 7) 上传产物到服务器(以下 5 个值均来自仓库 Secrets)#    - SSH_HOST:服务器 IP/域名(需改为你的)#    - SSH_USER:SSH 用户名(需改为你的)#    - SSH_PASSWORD:SSH 密码(如改用密钥见文档)#    - SSH_PORT:SSH 端口(默认 22,可按需修改)#    - REMOTE_PATH:部署目录(需改为你的,例如 /var/www/your-app)- name: Upload artifact to serveruses: appleboy/scp-action@v0.1.7with:host: ${{ secrets.SSH_HOST }}username: ${{ secrets.SSH_USER }}password: ${{ secrets.SSH_PASSWORD }}port: ${{ secrets.SSH_PORT }}source: "release.tar.gz"target: ${{ secrets.REMOTE_PATH }}# 8) 服务器上解压、装产线依赖并用 PM2 启动/热重载- name: Deploy on server (extract, install prod deps, reload pm2)uses: appleboy/ssh-action@v1.0.3with:host: ${{ secrets.SSH_HOST }}username: ${{ secrets.SSH_USER }}password: ${{ secrets.SSH_PASSWORD }}port: ${{ secrets.SSH_PORT }}script_stop: truescript: |set -ecd ${{ secrets.REMOTE_PATH }}mkdir -p currentmv release.tar.gz current/cd currenttar -xzf release.tar.gzrm -f release.tar.gz# 二次兜底:如提供了 ENV_FILE_CONTENTS,这里也会写入(与构建前一致)if [ ! -z "${{ secrets.ENV_FILE_CONTENTS }}" ]; thenecho "${{ secrets.ENV_FILE_CONTENTS }}" > .env.productionfi# 服务器仅安装生产依赖,减小体积npm ci --omit=dev# 使用 PM2 平滑重载;若无进程则创建if command -v pm2 >/dev/null 2>&1; thenpm2 startOrReload ecosystem.config.js --env production || pm2 start ecosystem.config.js --env productionpm2 saveelsenpm i -g pm2pm2 start ecosystem.config.js --env productionpm2 savefi
http://www.xdnf.cn/news/20150.html

相关文章:

  • SQL Server事务隔离级别
  • JavaScript 面向对象 原型和原型链 继承
  • 西嘎嘎学习-day 1
  • 栈:有效的括号
  • Dify-CHATflow案例
  • JS中的String的常用方法
  • Process Explorer 学习笔记(第三章3.2.3):工具栏与参考功能
  • 知微集:Python中的线程(三)
  • JavaScript 中的并发编程实践与误区:一次深入的探讨
  • 软考高级 — 系统规划与管理师考试知识点精要
  • 电脑活动追踪全解析:六款软件助企业实现数字化精细管理
  • whl编译命令作用解释
  • 【完整源码+数据集+部署教程】加工操作安全手套与手部检测系统源码和数据集:改进yolo11-cls
  • mysq集群高可用架构之组复制MGR(单主复制-多主复制)
  • 2025 年 8 个最佳网站内容管理系统(CMS)
  • 小迪安全v2023学习笔记(七十八讲)—— 数据库安全RedisCouchDBH2database未授权CVE
  • LeetCode 刷题【65. 有效数字】
  • 机器学习算法介绍二
  • postgresql 通过dblink实现 跨库查询
  • PostgreSQL收集pg_stat_activity记录的shell工具pg_collect_pgsa
  • zoho crm notes add customer fields
  • 数字人打断对话的逻辑
  • 本地 Ai 离线视频去水印字幕!支持字幕、动静态水印去除!
  • python-虚拟试衣
  • LVS、Nginx与HAProxy负载均衡技术对比介绍
  • 任意齿形的齿轮和齿条相互包络工具
  • Linux常见命令总结 合集二:基本命令、目录操作命令、文件操作命令、压缩文件操作、查找命令、权限命令、其他命令
  • Process Explorer 学习笔记(第三章3.2.5):状态栏信息详解
  • PyTorch 训练显存越跑越涨:隐式保留计算图导致 OOM
  • 机器学习周报十二