一、簡介
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:1180/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:1180/library/rapid-demo-back:v2.1.2
4、刪除本地映象
docker rmi 192.168.3.12:1180/library/rapid-demo-back:v2.1.2
5、Dockerfile內容
# jdk版本
FROM java:8
# 臨時檔案目錄
VOLUME /tmp
ADD target/*.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
二、前端打包
1、checkout程式碼下載
2、nodeJs打包
- 打包後目錄下會生成dist檔案
nodejs('node-v12.20.0') {
sh 'npm install --registry=https://registry.npm.taobao.org'
sh 'npm run build'
}
3、複製檔案
mv ../build_fronted_dist/dist ./dist
mv ../build_fronted_dist/Dockerfile ./Dockerfile
mv ../build_fronted_dist/nginx.conf ./nginx.conf
4、docker打包
docker build -t 192.168.3.12:1180/library/rapid-demo-web:v2.1.2 .
5、推送到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:1180/library/rapid-demo-web:v2.1.2
}
6、刪除本地映象
docker rmi 192.168.3.12:1180/library/rapid-demo-web:v2.1.2
7、Dockerfile內容
FROM nginx:alpine
COPY ./dist/ /usr/share/nginx/html/
COPY nginx.conf /etc/nginx/nginx.conf
8、nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server {
listen 8080;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
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:1180/library/rapid-demo-back:v2.1.2
4、啟動容器
docker run -d --name rapid-demo-back -p 6001:8080 192.168.3.12:1180/library/rapid-demo-back:v2.1.2
四、完整程式碼
1、pipeline script
pipeline {
agent any
environment{
dockerRegistry="192.168.3.12:1180"
//後端變數
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: false, description: '開啟後端構建')
booleanParam(name: 'ENABLE_FRONTED_BUILD', defaultValue: false, description: '開啟前端構建')
booleanParam(name: 'ENABLE_BACKEND_DEPLOY', defaultValue: false, description: '開啟後端部署')
booleanParam(name: 'ENABLE_FRONTED_DEPLOY', defaultValue: false, description: '開啟前端部署')
}
stages {
stage('初始化') {
steps {
echo '初始化。。。'
}
}
stage('後端打包'){
when{
expression{params.ENABLE_BACKEND_BUILD}
}
steps{
script{
ws("backend_build"){
dir("build_backend_docker"){
// 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: '8d4ff3de-9b05-427d-a211-23be72f65bbb', passwordVariable: 'password', usernameVariable: 'username')]) {
sh "docker login -u ${username} -p ${password} ${dockerRegistry}"
}
// docker推送至Harbor
sh "docker push ${backDockerImage}"
// 刪除映象
sh "docker rmi ${backDockerImage}"
}
echo '打包完成。。。'
// 刪除backend_build工作目錄
cleanWs()
}
}
}
}
//前端打包
stage('前端打包'){
when {
expression { params.ENABLE_FRONTED_BUILD }
}
steps {
script {
echo '前端打包。。。'
ws("fronted_build"){
dir("build_fronted_dist"){
// git程式碼拉取。。。
gitClone(frontGitUrl, frontBranch);
// nodejs的npm進行打包。。。
nodejs('node-v12.20.0') {
sh 'npm install --registry=https://registry.npm.taobao.org'
sh 'npm run build'
}
}
dir("build_fronted_docker"){
// 複製dist、dockerfile、nginx檔案。。。
sh "mv ../build_fronted_dist/dist ./dist"
sh "mv ../build_fronted_dist/Dockerfile ./Dockerfile"
sh "mv ../build_fronted_dist/nginx.conf ./nginx.conf"
// docker打包。。。
sh "docker build -t ${frontDockerImage} ."
// harbor登入
withCredentials([usernamePassword(credentialsId: '8d4ff3de-9b05-427d-a211-23be72f65bbb', passwordVariable: 'password', usernameVariable: 'username')]) {
sh "docker login -u ${username} -p ${password} ${dockerRegistry}"
}
// docker推送至Harbor
sh "docker push ${frontDockerImage}"
// 刪除映象
sh "docker rmi ${frontDockerImage}"
}
echo '打包完成。。。'
// 刪除backend_build工作目錄
cleanWs()
}
}
}
}
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_FRONTED_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='67cc51e8-9614-43c2-9ea1-2070ee9407c6'){
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 = 'b494c748-17fd-4356-8218-5131b5ea5b92') {
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" -p"${port}":"${serverPort}" $imageName
echo "容器啟動成功"
五、釋出測試
1、jenkins新建pipeline專案,使用上面的pipeline script
2、釋出測試
3、伺服器檢視專案是否啟動
4、訪問測試:192.168.3.15:7002
六、優化方案
1、新建docker-build工程,如下
2、新建pipeline專案
2、目錄介紹
- config:專案配置資訊,config.json配置了專案地址、docker資訊、釋出資訊等
- scripts:打包指令碼和釋出指令碼
- 公共變數:common_var.groovy
- 工具類:common_util.groovy
- 後端打包:build_backend.groovy
- 前端打包:build_fronted.groovy
- 後端釋出:publish_backend.groovy
- 前端釋出:publish_fronted.groovy
- Jenkinsfile:pipeline指令碼,jenkins專案選擇該檔案
- build_back:指令碼備份,deploy.sh通用釋出,Jenkinsfile未優化版
七、原始碼地址:
- 前端原始碼:https://gitee.com/lvlinguang/rapid-demo-web
- 後端原始碼:https://gitee.com/lvlinguang/rapid-demo-back
- docker-build:https://gitee.com/lvlinguang/docker-build
八、參考
- 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