开发环境目前前端团队自己管理,发版项目越来越多且频繁,决定自己搞一套jinkens 自动打包部署,网上搜了搜,都过老或者不可用,研究了三天终于完成了,写下分享给各位。
文章目录
- 前言
- 一、Docker 安装 Jinkens
- 1.系统要求
- 2. 安装
- 2.1 下载 镜像
- 2.2 docker 容器运行镜像
- 3. Jinkens 初始化
- 二、构建前端插件安装
- 三、使用pipeline 构建项目
- 1、新建任务
- 2、gitlab 触发器
- 2.1 配置gitlab 插件
- 2.2 选择触发器
- 2.2.1 切换到构建触发器选择:
- 3、构建项目pipeline 配置
- 4、前端构建Jinkensfile 脚本
- 4.1 node 环境
- 4.2 依赖安装和构建
- 4.3 部署
- 4.3.1 ssh 连接服务器
- 4.3.2 ngnix 发布shell 脚本
- 四、通知
- 1. 测试发送邮箱
- 2. 配置 Extended E-mail Notification
- 3. pipeline 发送邮箱脚本
- 全部Jenkinsfile 配置
前言
本文涉及一下内容:
- 在Linux 上使用Docker 部署Jenkins
- Jenkins初始化以及常用插件安装
- 使用pipeline 构建前端项目
- 添加gitlab触发器,提交代码合并请求时自动触发构建
- Jenkins 所在Docker容器Node 环境安装
- 前端项目安装构建
- 通过ssh 将前端项目发布到服务器
- ngnix 部署
- 发布完成邮件通知
安装系统:linux Docker版本:Docker version 19.03.5, build 633a0ea
一、Docker 安装 Jinkens
Docker 安装Jinkens 十分便利,注意的是对硬件要求较高。Docker就不赘述了,不明白的可以看看之前写过的一篇文章。
1.系统要求
最低推荐配置:
- 256MB可用内存
- 1GB可用磁盘空间(作为一个Docker容器运行jenkins的话推荐10GB)
为小团队推荐的硬件配置:
- 1GB 可用内存
- 50 GB 可用磁盘空间
注意:
最初在linux 上安装的分盘空间较小,安装插件的时候会遇到各种错误,重新安装位置比较麻烦
2. 安装
Docker镜像选择:
- jenkinsci/blueocean :捆绑了所有Blue Ocean插件和功能
- jenkins/jenkins
推荐jenkinsci/blueocean,这里下载 jenkinsci/blueocean镜像。
2.1 下载 镜像
执行docker -v
,确保已安装docker
执行docker pull jenkinsci/blueocean
下载镜像,下载完之后执行docker image ls
确保镜像下载成功。
2.2 docker 容器运行镜像
代码语言:javascript复制docker run
# 第一个主机端口(浏览器访问端口)随便填,第二个容器端口
-p 9090:8080
# 将jenkinsci/blueocean 容器的端口50000 映射到主机上的端口50000。
-p 50000:50000
# 将容器目录映射到本地目录。 :前端是你指定的服务器目录,后边固定
-v /data/jenkins-data:/var/jenkins_home
# 守护进程是必需的
-v /var/run/docker.sock:/var/run/docker.sock
jenkinsci/blueocean
3. Jinkens 初始化
执行docker ps
查看容器是否运行
运行之后即可浏览器访问 (http://服务器地址:9090/):
解锁 Jenkins 页面出现
按照其路径找到initialAdminbPassword
文件,vim 访问。
容器jinkens目录已映射到主机,在主机目录找到即可,我映射到了/data/jenkins-data/
文件夹。
复制密码继续下一步,然后按照推荐一步步安装即可,不多说。
二、构建前端插件安装
除了默认安装插件,我们还需要安装如下插件列表。
可以按照如下操作安装:
安装插件列表:
- GitLab Plugin :使用gitlab 提交合并动作的触发器,自动构建项目。
- SSH Pipeline Steps : 在pipeline 使用ssh 操作插件
- Docker plugin
- Docker Pipeline
- NodeJS Plugin
三、使用pipeline 构建项目
1、新建任务
选择新建任务,然后输入名字,选择流水线构建。
2、gitlab 触发器
首先先了解目标,我们期望项目在dev 开发环境push 或者 merge requeset 的时候自动构建。
2.1 配置gitlab 插件
确保下载完gitlab plugin之后,去系统工具下配置gitlab
设置名称、gitlab 部署host 和添加Gitlab API Token。
获取GitLab API token 步骤:
点击头像 -> settings
产生记下即可。
2.2 选择触发器
回到job的配置界面,查看gitlab 连接,选择刚才配置的名称。
2.2.1 切换到构建触发器选择:
勾选gitlab 改变时候构建,选择时间 push 和 允许合并请求的时候构建。
点击高级,因为我只想在开发环境构建dev 分支,所以需要分支过滤。
然后点击生成token 密码,用于gitlab 通知。
回到gitlab ,定位到仓库,选择 Settings -> Integrations,将webhook 和 生成的token 填入配置。 构建器步骤生成的
然后 add 添加webhook , 当以下Trigger 触发webhooks 通知jenkins。
到这里触发器完成,一会在jenkins 配置好仓库可以测试。
3、构建项目pipeline 配置
切换到流水线tab, 选择 Pipeline script from scm
然后输入仓库地址 和 gitlab 账号、密码。
指定分支和脚本路径: 图中设置 Jenkinsfile 即 在项目根目录 Jenkinsfile文件读入执行脚本。
4、前端构建Jinkensfile 脚本
示例项目是一个基于umi的React 项目,目录如下:
重点是Jenkinsfile 位置放到根目录。下面一一介绍pipeline 脚本文件Jenkinsfile构建前端的配置。
4.1 node 环境
构建前端应用需要node 环境,因为在docker容器中不能直接拿到宿主机node 。
这里使用pipeline agent 来指定代理环境。代理环境是docker 运行的node 镜像容器。
代码语言:javascript复制pipeline {
agent {
docker {
image 'node:16-alpine3.14'
args '-p 3000:3000'
}
}
stages {
stage('Node') {
steps {
sh 'node -v'
}
}
}
}
4.2 依赖安装和构建
利用 stages 流程分别执行,依赖安装和打包命令。
代码语言:javascript复制pipeline {
agent {
docker {
image 'node:16-alpine3.14'
args '-p 3000:3000'
}
}
stages {
stage('Install') {
steps {
sh 'npm install --registry=https://registry.npm.taobao.org'
}
}
stage('Build') {
steps {
sh 'npm run build:dev'
}
}
}
}
4.3 部署
执行完打包命令之后,在workspaces 文件夹里项目已经产生了dist 目录,但是现在在docker 容器内部,所以不能直接部署到ngnix。
那么需要借助ssh 连接到ngnix 服务器,将文件夹赋值到ngnix 和 使用 ngnix命令。
4.3.1 ssh 连接服务器
首先确保 SSH Pipeline Steps 插件是否安装。
然后Jenkinsfile 里建立连接脚本:
代码语言:javascript复制stage('Deploy'){
steps{
script{
def remote = [:]
remote.name = 'feService'
remote.host = '服务器ip'
remote.user = 'root'
remote.password = '服务器密码'
remote.allowAnyHosts = true
stage('Remote SSH') {
sshScript remote: remote, script: "deploy.sh"
}
}
}
}
4.3.2 ngnix 发布shell 脚本
连接到服务器这时候只需要,将web app 和 ngnix 配置拷贝到服务器部署。
部署有两种情况需要分别考虑:
- 第一次发布,配置启动
- 更新应用
ngnix 配置:
代码语言:javascript复制worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
server {
listen 端口号需要替换;
server_name localhost;
location / {
root html/项目名称;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
发布脚本deploy.sh:
代码语言:javascript复制PRO_NAME="项目名称"
if [! -f "/usr/local/nginx/conf/$PRO_NAME.conf"];then
echo "第一次需要新建配置文件,nginx 发布"
mv /data/jenkins-data/workspace/$PRO_NAME/$PRO_NAME.conf /usr/local/nginx/conf
mv /data/jenkins-data/workspace/$PRO_NAME/dist /usr/local/nginx/html/$PRO_NAME
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/$PRO_NAME.conf
else
echo "更新应用"
mv /data/jenkins-data/workspace/$PRO_NAME/dist /data/jenkins-data/workspace/$PRO_NAME/$PRO_NAME
cp -rf /data/jenkins-data/workspace/$PRO_NAME/$PRO_NAME /usr/local/nginx/html
rm -rf /data/jenkins-data/workspace/$PRO_NAME/$PRO_NAME
fi
这时候全部流程基本完成,但是缺少点啥。
四、通知
构建成功和失败需要通知,这里选择邮件通知,如果公司使用钉钉推荐用钉钉机器人接收。
使用 Email Extension Plugin 插件发送
1. 测试发送邮箱
系统配置中使用jenkins 自带邮件配置功能测试。
我这里使用的是163邮箱,需要去开启smtp。
jenkins 邮箱测试配置
注意: 这里注意如果是新邮箱刚开启smtp 服务,密码不是邮箱密码,是开启smtp产生的token
测试发送:
输入邮箱,测试成功接收即可。
2. 配置 Extended E-mail Notification
将测试的邮箱配置相同的写进来即可,这里有一个 内容模板,如果想发送的漂亮选择html 模板
3. pipeline 发送邮箱脚本
不管成功还是失败都去发送,指定发送模板。
代码语言:javascript复制 post {
always {
emailext (
subject: ''构建通知:${PROJECT_NAME} - Build # ${BUILD_NUMBER} - ${BUILD_STATUS}'',
body: '${FILE,path="jenkinsMail.html"}',
to: 'xxxx@qq.com'
)
}
}
html 模板:
代码语言:javascript复制<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>${ENV,var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志</title>
</head>
<body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4" offset="0">
<table width="95%" cellpadding="0" cellspacing="0"
style="font-size: 11pt; font-family: Tahoma,Arial,Helvetica,sans-serif">
<tr>
<td>(本邮件是程序自动下发,请勿回复!)</td>
</tr>
<tr>
<td><h2>
<font color="#0000FF">构建结果 - ${BUILD_STATUS}</font>
</h2></td>
</tr>
<tr>
<td><br />
<b><font color="#0B610B">构建信息</font></b>
<ht size="2" width="100%" byte="center" /></td>
</tr>
<tr>
<td>
<ul>
<li>项目名称 : ${PROJECT_NAME}</li>
<li>构建编号 : 第${BUILD_NUMBER}</li>
<li>触发方式 :${CAUSE}</li>
<li>构建日志 : <a href="${BUILD_URL}console">${BUILD_URL}console</a></li>
<li>构建 Url : <a href="${BUILD_URL}">${BUILD_URL}</a></li>
<li>工作目录 : <a href="${PROJECT_URL}workflow-stage">${PROJECT_URL}workflow-stage</a></li>
<li>项目 : Url : <a href="${PROJECT_URL}">${PROJECT_URL}</a></li>
</ul>
</td>
</tr>
<tr>
<td><font color="#0B610B">Changes Since Last
Successful Build:</font></b>
<hr size="2" width="100%" byte="center" /></td>
</tr>
<tr>
<td>
<ul>
<li>历史变更记录 : <a href="${PROJECT_URL}changes">${PROJECT_URL}changes</a></li>
</ul> ${CHANGES_SINCE_LAST_SUCCESS,reverse=true, format="Changes for Build #%n:<br />%c<br />",showPaths=true,changesFormat="<pre>[%a]<br />%m</pre>",pathFormat="%p"}
</td>
</tr>
<tr>
<td><b><font color="#0B610B">Failed Test Results</font></b>
<hr size="2" width="100%" byte="center" /></td>
</tr>
<tr>
<td><pre
style="font-size: 11pt; font-family: Tahoma,Aarial,Helvetica,sans-serif">$FAILED_TESTS</pre>
<br />
</td>
</tr>
<tr>
<td><font><font color="#0B610B">构建日志(最后100行):</font></b>
<hr size="2" width="100%" byte="center" /></td>
</tr>
<tr>
<td><textarea cols="80" rows="30" readonly="readonly"
style="font-family: Courier New">${BUILD_LOG,maxLines=100}</textarea>
</td>
</tr>
</table>
</body>
</html>
到此全部完成,感谢阅读。
全部Jenkinsfile 配置
代码语言:javascript复制pipeline {
agent {
docker {
image 'node:16-alpine3.14'
args '-p 3000:3000'
}
}
stages {
stage('Install') {
steps {
sh 'npm install --registry=https://registry.npm.taobao.org'
}
}
stage('Build') {
steps {
sh 'npm run build:dev'
}
}
stage('Deploy'){
steps{
script{
def remote = [:]
remote.name = 'feService'
remote.host = '服务器'
remote.user = 'root'
remote.password = '密码'
remote.allowAnyHosts = true
stage('Remote SSH') {
sshScript remote: remote, script: "deploy.sh"
}
}
}
}
}
post {
always {
emailext (
subject: ''构建通知:${PROJECT_NAME} - Build # ${BUILD_NUMBER} - ${BUILD_STATUS}'',
body: '${FILE,path="jenkinsMail.html"}',
to: 'xxx@qq.com'
)
}
}
}