前置环境
本教程所处环境:
操作系统: Windows 2012R2 服务器系统
JDK: Java 11
, 推荐(Java 17 或 Java 21) 这样的话可以在Jenkins中直接下载插件
软件: 宝塔面板 Jenkins 2.426.1
下载和安装
下载
到官网: Jenkins 下载最新的msi包, 然后运行:
下载的文件类型:
安装
双击下载的msi文件, 然后一路下一步即可.
但是这里我们选第一个
端口根据实际情况修改, 这里我后续改成了8999
Java路径根据实际情况修改, 这里我选的是jdk11的路径
然后就可以一直下一步了, 安装完成后, 会自动打开浏览器, 然后会提示输入密码, 这个密码在安装目录下的secrets/initialAdminPassword
文件中, 打开后复制粘贴即可.
如果没有自动打开浏览器, 可以手动打开浏览器, 输入http://localhost:8999
即可.
打开后如图:
直接按照提示输入密码即可.
然后我们点击自定义安装, 选择安装插件, 这里我们选择推荐插件
即可.
但是你会惊奇的发现所有的插件都是失败的, 这是因为我们的网络问题
(因为本教程是基于Java 11, 建议安装17 或者 21 版本解决这个问题, 下面有关插件安装问题可以忽略)
如图:
我们点击继续,进入到创建管理员界面, 这里我们可以直接点击继续
即可.
输入用户名和密码, 然后点击保存并完成
即可.
安装插件
如果前面的插件安装失败, 我们可以手动安装插件. 但是需要修改一下配置文件.
进入插件管理界面:
高级选项:
拉到下面, 修改升级站点
为http://mirror.esuni.jp/jenkins/updates/update-center.json
点击提交
即可.
有关镜像问题, 或许可以在这里尝试找到一些解决方案: 插件更新中心
汉化插件
我们需要安装汉化插件, 这样界面才是中文的.
我们去插件管理页面,点击可选插件
, 搜索Locale并安装:
然后再次搜索Localization
并安装(2个):
但是由于网络问题,插件大概率安装失败:
但是可以手动安装, 进入官网插件下载页面:
按顺序下载:
然后我们来到高级设置, 手动选择插件:
按顺序依次安装完毕后, 到系统设置设置默认语言zh_CN.
然后重启Jenkins即可(http://127.0.0.1:8999/restart)
必须插件
我们需要安装一些必须的插件, 这样才能使用Jenkins.
1.git
2.gitee
3.Generic Webhook Trigger Plugin
如果安装失败, 重复上面汉化的手动安装方式即可.
创建任务
我们需要创建一个任务, 这样才能使用Jenkins.
回到首页,点击create new jobs:
输入信息,选择Freestyle project:
点击OK
后, 进入到配置页面:
配置Gitee
去到系统设置, 点击Gitee配置,令牌个根据页面提示获取:
配置用户Token
进入到用户配置界面, 生成一个token并复制,然后保存
后面的gitee webHooks需要用到:
配置任务
刚才我们创建了一个任务, 现在我们需要配置任务.
源码管理
进入到任务配置界面, 点击源码管理, 选择git, 然后填写仓库地址
Credentials可以选择用户名密码, 也可以选择token, 这里我们选择token: (如果你的列表里面显示无, 那不选也没关系)
其它的可以不用管
构建触发器
如图,勾选Gitee webhook触发器
往下拉, 勾选Generic Webhook Trigger (如果没有这个选项, 去插件那里安装)
找到Token
输入框, 还记得在配置用户信息时复制的token吗, 这里我们需要粘贴进去: (每个项目都要重新生成一个新的token)
Build Steps
这里就是我们的项目该如何打包,甚至打包后我们该如何处理打包后的产物
根据项目的不同,这里我们配合宝塔面板的项目, 我们选择Windows batch command
然后输入打包和复制的命令:
npm run build
就是打包命令, 如果构建前需要安装依赖,可以在这命令之前加上npm install
xcopy /E/Y .\doc C:\wwwroot\doc
就是复制命令 将当前目录的doc文件夹复制到C:\wwwroot\doc
目录下
如果使用move
命令,会提示拒绝访问,有谁知道怎么解决吗😗
构建后的操作
这里填写后,当项目成功构建时,可以查看到构建的结果
目录的起始就是当前任务所处的文件夹的目录,doc就是打包后生成的文件夹,(原来是dist,可以在项目的配置文件中更改)
以下就是该任务的目录文件夹示意:
点击保存.
初次构建
终于来到这里了😂😂😂
我们回到任务页面, 点击Build Now
然后我们点击红框里面的内容,可以看到构建产生的文件,也可以看到控制台输出
构建完成如图所示
gitee WebHooks
进入gitee项目,然后找到WebHooks
配置WebHooks
URL的格式就是
http://管理系统的地址/generic-webhook-trigger/invoke?token=之前生成的用户的token
管理系统的地址 = jenkins.fanshu.xyz 或者 127.0.0.1:8999
(jenkins.fanshu.xyz这是我配置了域名)
然后点击保存返回WebHooks首页,点击测试:
有数据返回就是成功
如果是403就需要去系统设置里配置, 任何人可以做任何事😁
这一步如果配置成功,以后当我们向master分支推送代码时,会自动触发打包命令,并且把打包结果复制到宝塔的项目目录下
NextJS 项目部署
NextJS项目的部署跟一般的项目有区别,因为NextJS是SSR项目,所以需要在服务器上安装NodeJS并启动项目
在jenkins中配置Next项目
配置的流程跟上文差不多, 但要注意的是, 要配置gitee WebHooks时使用的token需要另外再jenkins中重新生成一个
不同的步骤是在构建步骤中, 需要另外配置
环境说明:
服务器: Windows 2012R2 服务器系统
web服务器: Nginx + NodeJS
进程管理: PM2
先梳理一下构建的步骤:
当代码推送到master分支时, 触发jenkins任务
停止
正在运行(划重点)
的pm2进程npm install 安装依赖 + npm run build 打包
通过pm2启动项目
流程是这样的, 那么我们就可以开始配置了
添加三个构建步骤
使用的是Execute Windows batch command
- 第一个是停止pm2进程
C:\Users\Administrator\AppData\Roaming\npm\pm2.cmd stop startNext
说明: startNext是进程的名称, 可以视为pm2 stop startNext
, 至于为什么不直接使用pm2执行, 后面会说到
- 第二个是安装依赖和打包
npm install && npm run build
- 第三个是启动pm2进程
C:\Users\Administrator\AppData\Roaming\npm\pm2.cmd start startNext.js
说明: startNext.js是在项目中配置的脚本, 可以视为pm2 start startNext.js
, 需要在jenkins对应的工作区的项目中创建
startNext.js所在目录结构:
内容如下:
const cmd = require('node-cmd')
cmd.run('npm run start')
正常情况下, 完整的命令可视为pm2 start --name startNext -- run start
至于为什么要配置startNext.js这个文件, 后面也会说到
至此, jenkins配置完成
问题说明
- 说明1: 由于jenkins + windows服务器的原因(也许是我不会配置), 在jenkins中执行pm2命令会有一下报错:
解决方法: 找到pm2的全路径, 使用全路径代替pm2命令:
C:\Users\Administrator\AppData\Roaming\npm\pm2.cmd stop startNext
- 说明2: 为什么要配置startNext.js这个文件
具体见: pm2在windows下的使用问题
这里我们采用第二种方法, 即使用第三方库node-cmd来执行命令
- 说明3: 还记得在梳理构建步骤时, 为什么强调要停止
正在运行
的pm2进程吗
因为如果名为startNext的进程没有在运行, pm2 stop startNext
会报错, jenkins任务会终止,
所以在这之前, 需要手动到服务器上执行一次pm2 start startNext.js
来启动进程
说明4: startNext在本文中指的是pm2进程的名称, 也是startNext.js的文件名, 可以自己定义
说明5: 如果在运行startNext.js脚本有以下报错:
提示模块找不到, 说明node-cmd包没有安装, 需要在你的next项目
中安装node-cmd包, 无论是在服务器上还是在你的本地正在开发的项目中
因为如果你本地的项目没安装, 推送代码后触发jenkins任务构建时, 会执行npm install
命令, 即使单独在服务器上安装了node-cmd包, 也会因此报错
- 说明6: 这里是能正常运行的完整的构建步骤的运行结果:
Started by user 1436393509
Running as SYSTEM
Building in workspace C:\ProgramData\Jenkins\.jenkins\workspace\Next JS
The recommended git tool is: NONE
No credentials specified
> C:\Program Files\Git\bin\git.exe rev-parse --resolve-git-dir C:\ProgramData\Jenkins\.jenkins\workspace\Next JS\.git # timeout=10
Fetching changes from the remote Git repository
> C:\Program Files\Git\bin\git.exe config remote.origin.url https://gitee.com/bigfanshu/next # timeout=10
Fetching upstream changes from https://gitee.com/bigfanshu/next
> C:\Program Files\Git\bin\git.exe --version # timeout=10
> git --version # 'git version 2.46.0.windows.1'
> C:\Program Files\Git\bin\git.exe fetch --tags --force --progress -- https://gitee.com/bigfanshu/next +refs/heads/*:refs/remotes/origin/* # timeout=10
> C:\Program Files\Git\bin\git.exe rev-parse "refs/remotes/origin/master^{commit}" # timeout=10
Checking out Revision 54aebcb678126a32c8a858c3d48748cb5ac60291 (refs/remotes/origin/master)
> C:\Program Files\Git\bin\git.exe config core.sparsecheckout # timeout=10
> C:\Program Files\Git\bin\git.exe checkout -f 54aebcb678126a32c8a858c3d48748cb5ac60291 # timeout=10
Commit message: "feat: 新增node-cmd包, 用于服务器启动服务"
> C:\Program Files\Git\bin\git.exe rev-list --no-walk 54aebcb678126a32c8a858c3d48748cb5ac60291 # timeout=10
[Next JS] $ cmd /c call C:\Windows\TEMP\jenkins4978947533365089111.bat
C:\ProgramData\Jenkins\.jenkins\workspace\Next JS>C:\Users\Administrator\AppData\Roaming\npm\pm2.cmd stop startNext
[PM2][Initialization] Environment variable HOME (Linux) or HOMEPATH (Windows) are not set!
[PM2][Initialization] Defaulting to /etc/.pm2
[PM2] Applying action stopProcessId on app [startNext](ids: [ 28 ])
[PM2] [startNext](28) ✓
┌────┬──────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼──────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0 │ app │ default │ N/A │ fork │ 70316 │ 14h │ 68 │ online │ 0% │ 14.0mb │ Adminis… │ disabled │
│ 1 │ app │ default │ 0.0.0 │ fork │ 3904 │ 3M │ 0 │ online │ 0% │ 13.8mb │ Adminis… │ disabled │
│ 28 │ startNext │ default │ 0.1.0 │ fork │ 0 │ 0 │ 15 │ stopped │ 0% │ 0b │ SYSTEM │ disabled │
└────┴──────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
[Next JS] $ cmd /c call C:\Windows\TEMP\jenkins8949722410654569939.bat
C:\ProgramData\Jenkins\.jenkins\workspace\Next JS>npm i && npm run build
up to date, audited 440 packages in 4s
141 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
> nextjs-example@0.1.0 build
> next build
▲ Next.js 15.1.0
Creating an optimized production build ...
✓ Compiled successfully
Linting and checking validity of types ...
Collecting page data ...
Generating static pages (0/8) ...
Generating static pages (2/8)
Generating static pages (4/8)
Generating static pages (6/8)
✓ Generating static pages (8/8)
Finalizing page optimization ...
Collecting build traces ...
Route (app) Size First Load JS
┌ ○ / 5.49 kB 111 kB
├ ○ /_not-found 979 B 106 kB
├ ○ /home 143 B 105 kB
├ ○ /home/about 143 B 105 kB
└ ○ /home/setting 143 B 105 kB
+ First Load JS shared by all 105 kB
├ chunks/4bd1b696-92810b4b4ece63ad.js 52.9 kB
├ chunks/517-c94eb82a0c6a5f4b.js 50.5 kB
└ other shared chunks (total) 1.95 kB
○ (Static) prerendered as static content
[Next JS] $ cmd /c call C:\Windows\TEMP\jenkins3681242134272783075.bat
C:\ProgramData\Jenkins\.jenkins\workspace\Next JS>C:\Users\Administrator\AppData\Roaming\npm\pm2.cmd start startNext.js
[PM2][Initialization] Environment variable HOME (Linux) or HOMEPATH (Windows) are not set!
[PM2][Initialization] Defaulting to /etc/.pm2
[PM2] Applying action restartProcessId on app [startNext](ids: [ 28 ])
[PM2] [startNext](28) ✓
[PM2] Process successfully started
┌────┬──────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼──────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0 │ app │ default │ N/A │ fork │ 70316 │ 14h │ 68 │ online │ 0% │ 10.3mb │ Adminis… │ disabled │
│ 1 │ app │ default │ 0.0.0 │ fork │ 3904 │ 3M │ 0 │ online │ 0% │ 9.3mb │ Adminis… │ disabled │
│ 28 │ startNext │ default │ 0.1.0 │ fork │ 71132 │ 1s │ 15 │ online │ 0% │ 31.4mb │ SYSTEM │ disabled │
└────┴──────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
Archiving artifacts
Finished: SUCCESS
可见startNext进程成功启动, 另外两个app是其他项目的进程
通过jenkins启动的进程, 会有一个SYSTEM的用户, 也就是说, 通过jenkins启动的进程, 会以SYSTEM用户的身份运行
- 说明7: 缓存问题
在nginx部署next项目时, 会有缓存问题, 会导致页面不更新, 需要在nginx配置文件中添加以下配置:
server {
listen 80;
// 配置的域名 可根据实际情况修改
server_name next.fanshu.xyz;
location / {
# 转发到本地服务
proxy_pass http://127.0.0.1:3000;
# 保留请求头信息
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 禁用代理缓存
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
add_header Pragma "no-cache";
expires off;
# 禁用 Nginx 内部缓存(确保不会缓存响应内容)
proxy_buffering off;
proxy_cache off;
# 禁用 ETag(可选,根据需求)
add_header ETag "";
}
}