devops-发布vue前端项目

news/2024/12/28 10:04:45/

回到目录

将使用jenkins+k8s发布前端项目

1 环境准备

node环境

在部署jenkins的服务器上搭建node环境

node版本

# 1.拉取
https://nodejs.org/download/release/v20.4.0/node-v20.4.0-linux-x64.tar.gz# 2.解压到/usr/local目录下
sudo tar xf v20.4.0.tar.gz -C /usr/local
#   重命名为node20
mv v20.4.0 node20# 3.配置环境变量
vim /etc/profile
export PATH=$PATH:/usr/local/node20/bin
#   文件生效
source /etc/profile# 4.软连接
sudo ln -s /usr/local/node20/bin/npm /usr/local/bin/
sudo ln -s /usr/local/node20/bin/node /usr/local/bin/# 5.验证
node -v
npm -v

验证环境没有问题后,将文件移动到jenkins的目录下

因为是docker部署的jenkins,挂载目录是/usr/local/docker/docker-jenkins/data,所以必须将node环境移动到该目录下,jenkins才能加载到

mv node20 /usr/local/docker/docker-jenkins/data

jenkins中下载nodejs插件

插件中搜索 nodejs

安装完成后重启,再次进入

在全局工具配置中,找到nodejs

安装目录为docker中jenkins的node目录,可进入docker jinkens容器中查看

2 项目构建

前提:在gitlab中创建一个vue项目,并确保该项目在本地能正常运行

我的项目结构如下,需要添加Dockerfile和jenkinsfile以及deploy目录

 

创建完成后编写jenkinsfile

pipeline{agent anyenvironment {//gitlab访问凭证GIT_CREDENTIAL_ID = 'gitlab-root'//gitlab地址GIT_REPO_URL = '10.1.9.23:28080'//gitlab分组GIT_GROUP = 'devops'//gitlab项目名称GIT_NAME = 'fitmentfront'//harbor凭证HARBOR_ID = 'harbor-admin'//harbor地址HARBOR_URL = '39.10.18.1:8858'//harbor项目HARBOR_REPO = 'repo'//发送delpoment.yml到k8s服务器上的地址K8S_FILE_PATH = '/opt/k8s/deployfile'//gitlab发送到服务器的目录GITLAB_DEPLOYMENT_FILE = 'deploy'}parameters {//git插件 分支参数gitParameter(branchFilter: '.*',defaultValue: "${env.BRANCH_NAME ?: 'main'}",name: 'BRANCH_NAME',type: 'PT_BRANCH',description: '请选择要发布的分支')//git插件 标签参数gitParameter(branchFilter: '.*',defaultValue: "${env.TAG_NAME ?: 'v:1.0.0'}",name: 'TAG_NAME',type: 'PT_TAG',description: '请选择要发布的标签')}stages{stage("基本信息输出"){steps{echo '选定待发布信息'echo "项目地址    ${GIT_REPO_URL}"echo "项目组      ${GIT_GROUP}"echo "项目名      ${GIT_NAME}"echo "分支        ${BRANCH_NAME}"echo "TAG        ${TAG_NAME}"}}stage('拉取gitlab代码') {steps {//拉取gitlab代码,选择分支checkout scmGit(branches: [[name: env.BRANCH_NAME]],extensions: [],userRemoteConfigs: [[credentialsId: env.GIT_CREDENTIAL_ID,url: "http://${env.GIT_REPO_URL}/${env.GIT_GROUP}/${env.GIT_NAME}.git"]])echo '拉取gitlab代码  --SUCCESS'}}stage("编译"){steps{nodejs('node') {// some blocksh '''npm install --registry=https://registry.npmmirror.comnpm run build'''}}}stage("构建镜像"){steps {//docker制作镜像//将maven打包的jar移动到docker目录下//使用dockerfile进行构建镜像,镜像名称为 项目名:标签sh """echo $PWDdocker build -t ${env.GIT_NAME}:${env.TAG_NAME} ."""echo '通过docker制作镜像  --SUCCESS'}}stage('推送镜像到harbor') {steps {//使用harbor凭证推送镜像withCredentials([usernamePassword(credentialsId: env.HARBOR_ID,passwordVariable: 'DOCKER_PASSWORD',usernameVariable: 'DOCKER_USERNAME')]) {//打标签为远程仓库标签//登陆到harbor//推送镜像sh """docker tag ${env.GIT_NAME}:${env.TAG_NAME} ${env.HARBOR_URL}/${env.HARBOR_REPO}/${env.GIT_NAME}:${env.TAG_NAME}echo "\$DOCKER_PASSWORD" | docker login -u "\$DOCKER_USERNAME" -p "\$DOCKER_PASSWORD" ${env.HARBOR_URL}docker push ${env.HARBOR_URL}/${env.HARBOR_REPO}/${env.GIT_NAME}:${env.TAG_NAME}"""}echo '推送镜像到harbor  --SUCCESS'}}stage('发送k8s部署yml文件至目标服务器') {steps {//请空文件夹下所有文件内容sh """ssh root@10.199.99.200 rm -rf $K8S_FILE_PATH/*"""//使用ssh插件 发送deploy目录下的部署yml文件到目标服务器//须提前配置ssh免密登陆sshPublisher(publishers: [sshPublisherDesc(configName: 'k8s',transfers: [sshTransfer(cleanRemote: false,excludes: '',execCommand: '',execTimeout: 120000,flatten: false,makeEmptyDirs: false,noDefaultExcludes: false,patternSeparator: '[, ]+',remoteDirectory: '',remoteDirectorySDF: false,removePrefix: '',sourceFiles: "${env.GITLAB_DEPLOYMENT_FILE}/*yaml")],usePromotionTimestamp: false,useWorkspaceInPromotion: false,verbose: false)])echo '发送yml文件至目标服务器  --SUCCESS'}}stage('远程执行k8s部署yaml命令') {steps {//替换发送过来的部署文件//部署sh """ssh root@10.19.99.200 sed -i'' "s#REGISTRY#${env.HARBOR_URL}#" ${env.K8S_FILE_PATH}/${env.GITLAB_DEPLOYMENT_FILE}/deployment.yamlssh root@10.19.99.200 sed -i'' "s#DOCKERHUB_NAMESPACE#${env.HARBOR_REPO}#" ${env.K8S_FILE_PATH}/${env.GITLAB_DEPLOYMENT_FILE}/deployment.yamlssh root@10.19.99.200 sed -i'' "s#APP_NAME#${env.GIT_NAME}#" ${env.K8S_FILE_PATH}/${env.GITLAB_DEPLOYMENT_FILE}/deployment.yamlssh root@10.19.99.200 sed -i'' "s#BUILD_NUMBER#${env.TAG_NAME}#" /${env.K8S_FILE_PATH}/${env.GITLAB_DEPLOYMENT_FILE}/deployment.yamlssh root@10.19.99.200 kubectl apply -f ${env.K8S_FILE_PATH}/${env.GITLAB_DEPLOYMENT_FILE}/"""echo '远程执行k8s部署yaml命令  --SUCCESS'}}}
}

 Dockerfile

FROM node:14-alpine AS build
WORKDIR /build/fitment
COPY . .
RUN npm install --registry=https://registry.npmmirror.com && npm run buildFROM nginx:1.22
WORKDIR /app/fitment
COPY --from=build /build/fitment/dist .
EXPOSE 80

deploy中的deployment.yaml

apiVersion: v1
kind: Namespace
metadata:name: fitment
---
apiVersion: v1
kind: ConfigMap
metadata:name: fitment-confnamespace: fitmentlabels:app: nginx-conf
data:nginx.conf: |server {listen  80;server_name localhost;location / {root /app/fitment;index index.html index.htm;}location /api/ {#设置请求头等,防止出现跨域问题proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header REMOTE-HOST $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass http://fitmentback.fitment/; #设置监控后端启动的端口}error_page 500 502 503 504 /50x.html;location = /50x.html {root    html;}}
---
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: fitmet-uicomponent: fitment-devopstier: frontname: fitmet-uinamespace: fitment
spec:progressDeadlineSeconds: 600replicas: 1selector:matchLabels:app: fitmet-uicomponent: fitment-devopstier: frontstrategy:rollingUpdate:maxSurge: 100%maxUnavailable: 100%type: RollingUpdatetemplate:metadata:labels:app: fitmet-uicomponent: fitment-devopstier: frontspec:imagePullSecrets:- name: harbor-secretcontainers:- name: fitmet-uiimage: REGISTRY/DOCKERHUB_NAMESPACE/APP_NAME:BUILD_NUMBERimagePullPolicy: Alwaysports:- containerPort: 80protocol: TCPlivenessProbe:httpGet:path: /port: 80initialDelaySeconds: 30timeoutSeconds: 5failureThreshold: 5periodSeconds: 10readinessProbe:httpGet:path: /port: 80initialDelaySeconds: 20timeoutSeconds: 5failureThreshold: 3periodSeconds: 10resources:limits:cpu: 300mmemory: 600Mirequests:cpu: 100mmemory: 100MiterminationMessagePath: /dev/termination-logterminationMessagePolicy: FilevolumeMounts:- name: nginx-confmountPath: /etc/nginx/conf.d/volumes:- name: nginx-confconfigMap:name: fitment-confitems:- key: nginx.confpath: nginx.conf   dnsPolicy: ClusterFirstrestartPolicy: AlwaysterminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:labels:app: fitmet-uicomponent: fitment-devopsname: fitmet-uinamespace: fitment
spec:ports:- name: httpport: 80protocol: TCPtargetPort: 80selector:app: fitmet-uicomponent: fitment-devopstier: frontsessionAffinity: Nonetype: NodePort
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: fitment-ui-ingressnamespace: fitmentannotations:kubernetes.io/ingress.class: "nginx"nginx.ingress.kubernetes.io/rewrite-target: /
spec:rules:- host: fitment.fooleryang.cn # 域名配置,可以使用通配符 *http:paths: # 相当于 nginx 的 location 配置,可以配置多个- pathType: Prefix # 路径类型,按照路径类型进行匹配 ImplementationSpecific 需要指定 IngressClass,具体匹配规则以 IngressClass 中的规则为准。Exact:精确匹配,URL需要与path完全匹配上,且区分大小写的。Prefix:以 / 作为分隔符来进行前缀匹配backend:service:name: fitmet-ui # 代理到哪个 serviceport:number: 80 # service 的端口path: /

3 jenkins创建项目

在vue项目的准备工作完成后【本地运行正常,各个文件准备完成、提交到gitlab中】,创建jenkins流水线项目

执行构建,然后停止【目的:拉取源码的jenkinsfile,得到参数化构建配置】

执行第一次构建后参数化配置即会出现

再次选择tag进行构建

 构建完成后,去k8s中查看相应pod,发现处于运行状态

[root@k8s-master k8s]# kubectl get all -n fitment
NAME                            READY   STATUS    RESTARTS   AGE
pod/fitmet-ui-76c68f444-thm74   1/1     Running   0          23mNAME                TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/fitmet-ui   NodePort   10.106.206.48   <none>        80:30800/TCP   37mNAME                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/fitmet-ui   1/1     1            1           37mNAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/fitmet-ui-76c68f444   1         1         1       37m

访问

可以用配置的ingress进行访问,也可以使用nodeport进行访问

成功访问,说明发布成功

 


http://www.ppmy.cn/news/1006580.html

相关文章

双向带头循环链表+OJ题讲解

&#x1f493;博主个人主页:不是笨小孩&#x1f440; ⏩专栏分类:数据结构与算法&#x1f440; 刷题专栏&#x1f440; C语言&#x1f440; &#x1f69a;代码仓库:笨小孩的代码库&#x1f440; ⏩社区&#xff1a;不是笨小孩&#x1f440; &#x1f339;欢迎大家三连关注&…

熟练掌握ChatGPT解决复杂问题——学会提问

目录 引言 一、5W1H分析法 1. 简单的问题&#xff08;what、where、when、who&#xff09; 2.复杂的问题&#xff08;why、how&#xff09; 2.1 为什么&#xff08;Why&#xff09;——原因 2.2 方式 &#xff08;How&#xff09;——如何 二、如何提问得到更高质量的答案…

Selenium自动化测试框架的搭建

说 起自动化测试&#xff0c;我想大家都会有个疑问&#xff0c;要不要做自动化测试&#xff1f; 自动化测试给我们带来的收益是否会超出在建设时所投入的成本&#xff0c;这个嘛别说是我&#xff0c;即便是高手也很难回答&#xff0c;自动化测试的初衷是美好的&#xff0c;而测…

JVM基础篇-StringTable

StringTable 特性 常量池中的字符串仅是符号&#xff0c;第一次用到时才变为对象 利用串池的机制&#xff0c;来避免重复创建字符串对象 字符串变量拼接的原理是 StringBuilder &#xff08;1.8&#xff09; 字符串常量拼接的原理是编译期优化 可以使用 intern 方法&#…

go 基本语法(简单案例)

&#xff01;注&#xff1a; go中 对变量申明很是严格&#xff0c;申明了&#xff0c;在没有使用的情况下&#xff0c;也会产生编译错误 1.行分隔符 一行就是代码&#xff0c;无&#xff1b;分割&#xff0c;如果需要在一行展示&#xff0c;需要以&#xff1b;分割&#xff0c;…

最新SecureCRT 中文注册版

SecureCRT是一款由VanDyke Software公司开发的终端仿真软件&#xff0c;它提供了类似于Telnet和SSH等协议的远程访问功能。SecureCRT专门为网络管理员、系统管理员和其他需要保密访问网络设备的用户设计。 软件下载&#xff1a;SecureCRT for ma注册版 远程访问&#xff1a;Sec…

C++20 协程(coroutine)入门

文章目录 C20 协程&#xff08;coroutine&#xff09;入门什么是协程无栈协程和有栈协程有栈协程的例子例 1例 2 对称协程与非对称协程无栈协程的模型无栈协程的调度器朴素的单线程调度器让协程学会等待Python 中的异步函数可等待对象M:N 调度器——C# 中的异步函数 小结 C20 中…

python数据处理程序代码,如何用python处理数据

大家好&#xff0c;给大家分享一下python数据处理程序代码&#xff0c;很多人还不知道这一点。下面详细解释一下。现在让我们来看看&#xff01; 要求&#xff1a;分别以james&#xff0c;julie&#xff0c;mikey&#xff0c;sarah四个学生的名字建立文本文件&#xff0c;分别存…