jenkins+docker项目发布
一、简介
1、该章节基于jenkins、Harbor、pipeline来做发布,如对这些不熟悉,请按以下进入学习
2、jenkins学习地址:https://www.cnblogs.com/lvlinguang/p/15163691.html
3、Harbor学习地址:https://www.cnblogs.com/lvlinguang/p/15500171.html
4、pipeline学习地址:https://www.cnblogs.com/lvlinguang/p/15512349.html
二、docker打包
一、后端打包
1、git代码拉取
// 使用checkout拉取代码
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: 'a8db6793-cc2b-4d82-bd3d-c5beb1c5149e', url: 'https://gitee.com/lvlinguang/rapid-demo-back.git']]])
// 使用git branch拉取代码
git branch: 'master', credentialsId: 'a8db6793-cc2b-4d82-bd3d-c5beb1c5149e', url: 'https://gitee.com/lvlinguang/rapid-demo-back.git'
2、mvn打包
mvn -U clean install -Dmaven.test.skip=true
3、docker打包
- 使用maven插件打包并推送到Harbor
mvn dockerfile:build dockerfile:push
- 使用docker打包并推送到Harbor
// docker打包
docker build -t 192.168.3.12:6007/library/rapid-demo-back:v2.1.2 .
// harbor登录
withCredentials([usernamePassword(credentialsId: '8d4ff3de-9b05-427d-a211-23be72f65bbb', passwordVariable: 'password', usernameVariable: 'username')]) {
sh "docker login -u ${username} -p ${password} ${dockerRegistry}"
}
// docker推送到Harbor
docker push 192.168.3.12:6007/library/rapid-demo-back:v2.1.2
4、删除本地镜像
docker rmi 192.168.3.12:6007/library/rapid-demo-back:v2.1.2
5、Dockerfile内容
# jdk版本
FROM moxm/java:1.8-full
# 临时文件目录
VOLUME /tmp
ADD target/*.jar app.jar
ENTRYPOINT ["java","-jar","app.jar","-Xms512m","-Xmx1024m","-Djava.security.egd=file:/dev/./urandom"]
二、前端打包
1、checkout代码下载
2、nodeJs打包
- 打包后目录下会生成dist文件
nodejs('node-v12.20.0') {
sh 'npm install --registry=https://registry.npm.taobao.org'
sh 'npm run build'
}
3、docker打包
docker build -t 192.168.3.12:6007/library/rapid-demo-web:v2.1.2 .
4、推送到Harbor
withCredentials([usernamePassword(credentialsId: '8d4ff3de-9b05-427d-a211-23be72f65bbb', passwordVariable: 'password', usernameVariable: 'username')]) {
// harbor登录
sh "docker login -u ${username} -p ${password} ${dockerRegistry}"
// 推送Harbor
docker push 192.168.3.12:6007/library/rapid-demo-web:v2.1.2
}
5、删除本地镜像
docker rmi 192.168.3.12:6007/library/rapid-demo-web:v2.1.2
6、Dockerfile内容
FROM nginx:alpine
# 作者信息
MAINTAINER lvlinguang <635074566@qq.com>
# 复制html页面
COPY ./dist ./usr/share/nginx/html/
# 复制nginx配置文件
COPY ./default.conf /etc/nginx/conf.d/
7、default.conf
server {
listen 8080;
#listen [::]:80;
server_name localhost;
gzip on;
gzip_min_length 1000;
gzip_comp_level 6;
gzip_types text/plain application/xml application/javascript application/x-javascript text/css application/xml;
gzip_vary on;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
# 后端接口代理
# location /screen {
# proxy_set_header Host $http_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;
# proxy_pass http://192.168.3.15:6032/;
# }
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
三、启动容器
1、查询容器是否存在,存在则删除
# 容器id
containerId=$(docker ps -a | grep -w "rapid-demo-back" | awk '{print $1}')
if [ "$containerId" != "" ] ;
then
#停掉容器
docker stop "$containerId"
#删除容器
docker rm "$containerId"
fi
2、查询镜像是否存在,存在则删除
# 镜像id
imageId=$(docker images | grep -w "rapid-demo-back" | awk '{print $3}')
if [ "$imageId" != "" ] ;
then
#删除镜像
docker rmi -f "$imageId"
fi
3、下载镜像
docker pull 192.168.3.12:6007/library/rapid-demo-back:v2.1.2
4、启动容器
docker run -d --name rapid-demo-back --restart=always -p 6001:8080 192.168.3.12:6007/library/rapid-demo-back:v2.1.2
四、完整代码
1、pipeline script
pipeline {
agent any
environment{
dockerRegistry="192.168.3.12:6007"
//后端变量
backPort=7001
backServerPort=8080
backName="rapid-demo-back"
backGitUrl="https://gitee.com/lvlinguang/rapid-demo-back.git"
backBranch="*/master"
backDockerImage="${dockerRegistry}/library/${backName}:v2.1.2"
//前端变量
frontPort=7002
frontServerPort=8080
frontName="rapid-demo-web"
frontGitUrl="https://gitee.com/lvlinguang/rapid-demo-web.git"
frontBranch="*/master"
frontDockerImage="${dockerRegistry}/library/${frontName}:v2.1.2"
}
parameters {
booleanParam(name: 'ENABLE_BACKEND_BUILD', defaultValue: true, description: 'docker后端构建')
booleanParam(name: 'ENABLE_FRONTEND_BUILD', defaultValue: true, description: 'docker前端构建')
booleanParam(name: 'ENABLE_BACKEND_DEPLOY', defaultValue: true, description: 'docker后端部署')
booleanParam(name: 'ENABLE_FRONTEND_DEPLOY', defaultValue: true, description: 'docker前端部署')
}
post {
always {
// 删除工作目录
cleanWs()
}
}
stages {
stage('初始化') {
steps {
echo '初始化。。。'
}
}
stage('后端打包'){
when{
expression{params.ENABLE_BACKEND_BUILD}
}
steps{
script{
// git代码拉取。。。
gitClone(backGitUrl, backBranch);
// mvn打包。。。
sh "/usr/local/apache-maven-3.8.2/bin/mvn -U clean install -Dmaven.test.skip=true"
// docker打包。。。
sh "docker build -t ${backDockerImage} ."
// harbor登录
withCredentials([usernamePassword(credentialsId: '6a2f3d27-7641-4666-90e1-833c39afde8d', passwordVariable: 'password', usernameVariable: 'username')]) {
sh "docker login -u ${username} -p ${password} ${dockerRegistry}"
}
// docker推送至Harbor
sh "docker push ${backDockerImage}"
// 删除镜像
sh "docker rmi ${backDockerImage}"
echo '打包完成。。。'
}
}
}
//前端打包
stage('前端打包'){
when {
expression { params.ENABLE_FRONTEND_BUILD }
}
steps {
script {
echo '前端打包。。。'
// git代码拉取。。。
gitClone(frontGitUrl, frontBranch);
// nodejs的npm进行打包。。。
nodejs('node-v12.20.0') {
sh 'npm install --registry=https://registry.npm.taobao.org'
sh 'npm run build'
}
// docker打包。。。
sh "docker build -t ${frontDockerImage} ."
// harbor登录
withCredentials([usernamePassword(credentialsId: '6a2f3d27-7641-4666-90e1-833c39afde8d', passwordVariable: 'password', usernameVariable: 'username')]) {
sh "docker login -u ${username} -p ${password} ${dockerRegistry}"
}
// docker推送至Harbor
sh "docker push ${frontDockerImage}"
// 删除镜像
sh "docker rmi ${frontDockerImage}"
echo '打包完成。。。'
}
}
}
stage('测试') {
steps {
echo '测试。。。'
}
}
stage('后端发布') {
when{
expression{params.ENABLE_BACKEND_DEPLOY}
}
steps {
script {
echo '后端发布。。。'
// 远程服务器
def sshServer = getRemoteServer('192.168.3.15')
//remote发布
sshCommand remote: sshServer, command: "/usr/local/java/deploy.sh $backName $backDockerImage $backPort $backServerPort"
}
}
}
stage('前端发布') {
when{
expression{params.ENABLE_FRONTEND_DEPLOY}
}
steps {
script{
echo '前端发布。。。'
// 远程服务器
def sshServer = getRemoteServer('192.168.3.15')
//remote发布
sshCommand remote: sshServer, command: "/usr/local/java/deploy.sh $frontName $frontDockerImage $frontPort $frontServerPort"
}
}
}
}
}
//获取远程服务器
def getRemoteServer(String ip='192.168.3.15',String credentialsId='6c17706c-f96f-4711-91e4-719234985cba'){
def remote = [:]
remote.name = ip
remote.host = ip
remote.port = 22
remote.allowAnyHosts = true
withCredentials([usernamePassword(credentialsId: credentialsId, passwordVariable: 'password', usernameVariable: 'username')]) {
remote.user = "${username}"
remote.password = "${password}"
}
return remote
}
//git代码下载
def gitClone(String gitUrl, String gitBranch, String credentialsId = 'abd46afe-05df-4de1-a683-edefb9319110') {
checkout([
$class : 'GitSCM',
branches : [[name: gitBranch]],
extensions : [],
userRemoteConfigs: [[
credentialsId: credentialsId,
url : gitUrl
]]
])
}
2、deploy.sh
#接收外部参数,由jenkinsfile执行部署脚本时传递
projectName=$1
imageName=$2
port=$3
serverPort=$4
echo "镜像名: $imageName"
echo "项目名: $projectName"
# 容器id
containerId=$(docker ps -a | grep -w "${projectName}" | awk '{print $1}')
if [ "$containerId" != "" ] ;
then
#停掉容器
docker stop "$containerId"
#删除容器
docker rm "$containerId"
echo "成功删除容器"
fi
# 镜像id
imageId=$(docker images | grep -w "${projectName}" | awk '{print $3}')
if [ "$imageId" != "" ] ;
then
#删除镜像
docker rmi -f "$imageId"
echo "成功删除镜像"
fi
# 镜像下载
docker pull "$imageName"
# 启动容器
docker run -d --name "$projectName" --restart=always -p"${port}":"${serverPort}" $imageName
echo "容器启动成功"
五、发布测试
1、jenkins新建pipeline项目,使用上面的pipeline script
2、发布测试
3、服务器查看项目是否启动
4、访问测试:192.168.3.15:7002
六、优化方案
1、使用docker-build工程,请参考我的另一篇文章
- 学习地址:https://www.cnblogs.com/lvlinguang/p/15712328.html
- Build with Parameters 选择docker部署,如下图
七、源码地址
八、参考
- https://www.jianshu.com/p/1401e2fe4711
- remote ssh使用:https://www.cnblogs.com/dreamer-fish/p/13524138.html
- nodeJs安装:https://blog.csdn.net/liumiaocn/article/details/102618269
- npm淘宝镜像设置:https://www.jianshu.com/p/1d8debb671a7
- vue项目部署:https://www.cnblogs.com/blue-rain/p/12463133.html
- vue项目部署:https://blog.csdn.net/mumushuiding/article/details/94452574