过去我们都是使用自己搭建的harbor
私有镜像仓库,基本上还算流畅,也出现过几次问题:域名证书过期、服务器磁盘满了、服务器带宽不够,主要是带宽不够这个问题,镜像文件太大了就造成速度慢甚至超时。
后来知道腾讯云有容器镜像服务,原打算让公司花2w买三年企业版,但是呢一直没得到支持,查文档看到个人免费版是可以推100个镜像,而且会自动清理,那就满足我们需求了。
进入腾讯云管理控制台,找到 容器镜像服务
已经新建 cyrjhub,以后所有项目都用这个命名控件即可
回到jenkins里面在全局凭据中添加 腾讯云镜像仓库账号密码
以前端sci-web为例,同原来自建Harbor,只有改三个地方:新地址、命名控件和凭据ID,这三个地方在以后项目中都是固定的用这三个即可
1、 harborServer、harborInnerSite 这两个其实可只用一个了,可以去掉harborInnerSite,都用harborServer,以前是因为自己搭建的harbar仓库,带宽限制做了内外网优化
2、 harborLibrary 这里是固定 chub,上面在腾讯云控制台建的命名空间
3、 tengx_docker_personal 有两处用到,一是jenkins服务器上push镜像,二是目标服务器pull镜像,这个名字是上面全局凭据自己写的ID名称
// 注意先建system凭据
pipeline {
agent any
environment {
// 毫秒做镜像标签
imageTag = sh(script: "echo `date '+%Y%m%d%H%M%S'`", returnStdout: true).trim()
// harbor仓库
harborServer = 'ccr.ccs.tencentyun.com' // 腾讯云固定
harborLibrary = 'chub' // 腾讯云固定用这个
// git项目
gitServer = 'http://xxx.xxx.xxx.xxx:30300/' // 可以修改,git仓库地址
gitGroup = 'root' // 可以修改,git里面项目分组名
gitProjectName = 'jeecg-nest-server' // 可以修改,git项目名称
// 后端接口,区分开测试环境和生产环境
testApiServer = 'http://172.16.0.xxx' // 测试服务器内网ip
proApiServer = 'http://172.17.0.xxx' // 生产服务器内网ip
// 服务器ssh地址
testSshServer = 'xxx.xxx.xxx.xxx' // 测试服务器外网ip
proSshServer = 'xxx.xxx.xxx.xxx' // 生产服务器外网ip
}
parameters {
// gitParameter name:'MR_TO_BRANCH',
// type:'PT_BRANCH_TAG',
// branchFilter:'origin/(.*)',
// defaultValue:'dev',
// selectedValue:'DEFAULT',
// sortMode:'DESCENDING_SMART',
// description:'选择分支'
choice(
choices: "test\npro", name:'buildType', description:'选择发布环境,test服119,pro服195'
)
// string( name: 'MR_TO_BRANCH', defaultValue: 'master', description: '输入分支', trim: true)
choice(
choices: "master\ndev\nnewui\ntest-template\ntest-sentry", name:'MR_TO_BRANCH', description:'输入分支'
)
choice(
choices: "3001", name:'apiDokerPort', description:'nest后端发布端口'
)
}
stages {
stage('拉取代码') {
steps {
script {
if(params.buildType == 'test'){
env.apiServer = "${env.testApiServer}:${apiDokerPort}"
env.sshServer = env.testSshServer
env.sshPort = 22
}
if(params.buildType == 'pro'){
env.apiServer = "${env.proApiServer}:${apiDokerPort}"
env.sshServer = env.proSshServer
env.sshPort = 12358
}
env.dockerImageName = "${gitProjectName}_${buildType}_${apiDokerPort}"
}
git branch: "${MR_TO_BRANCH}",credentialsId: 'gitlabroot', url: "${gitServer}/${gitGroup}/${gitProjectName}.git"
}
}
stage('代码构建') {
steps {
script{
sh '''
npm install --force
npm run build
'''
}
}
}
stage('打包docker') {
steps {
script{
sh '''
docker build -t ${harborServer}/${harborLibrary}/${dockerImageName}:${imageTag} .
'''
}
}
}
stage('推送镜像') {
steps {
script{
withCredentials([usernamePassword(credentialsId: 'tengx_docker_personal', passwordVariable: 'harbor_password', usernameVariable: 'harbor_username')]) {
sh '''
docker login -u ${harbor_username} -p ${harbor_password} ${harborServer}
docker push ${harborServer}/${harborLibrary}/${dockerImageName}:${imageTag}
'''
}
}
}
}
stage('清理镜像') {
steps {
script{
catchError(buildResult:'SUCCESS', stageResult:'SUCCESS'){
// 1、清理当前镜像 2、清理2天前历史缓存中间镜像
sh '''
docker rmi -f ${harborServer}/${harborLibrary}/${dockerImageName}:${imageTag}
docker images -f "dangling=true" '--format={{.Tag}} {{.ID}} {{.CreatedAt}}' | awk '{CS=mktime(sprintf("%s %s %s 00 00 00",substr($3,0,4),substr($3,6,2),substr($3,9,2)));ID=$2;NS=systime();DT=NS-2*86400;if(DT > CS){print ID}}' | xargs -r docker rmi -f
'''
// 不移除空白的镜像,因为那些是docker分层缓存 2023.09.08
// docker rmi -f $(docker images | grep "none" | awk '{print $3}')
// docker自带清理缓存10天前
// docker builder prune --filter 'until=240h' -f
}
}
}
}
stage('部署') {
steps {
script{
// 测试环境要打包+发布;生成环境只打包
withCredentials([usernamePassword(credentialsId: 'tengx_docker_personal', passwordVariable: 'harbor_password', usernameVariable: 'harbor_username')]) {
sh '''
SSHCMD="
docker login -u ${harbor_username} -p ${harbor_password} ${harborServer};
docker pull ${harborServer}/${harborLibrary}/${dockerImageName}:${imageTag};
docker ps -a --filter 'name=${dockerImageName}' -aq | xargs -r docker rm -f;
docker images | grep '${dockerImageName}' | grep -nv '${imageTag}' | awk '{print $3}'| xargs -r docker rmi -f;
docker run -d --restart always --name ${dockerImageName} -v /home/${dockerImageName}/db/:/app/db/ -p ${apiDokerPort}:3000 ${harborServer}/${harborLibrary}/${dockerImageName}:${imageTag};
"
ssh -p ${sshPort} root@${sshServer} ${SSHCMD}
'''
}
}
}
}
// stage('清理腾讯云') {
// steps {
// script{
// sh '''
// sleep 1
// sh /var/jenkins_home/workspace/DeleteImagePersonal.sh ${harborLibrary}/${dockerImageName} ${imageTag}
// '''
// }
// }
// }
stage('打印结果') {
steps {
script {
echo "本次构建 ${params.buildType} 完成:"
echo "镜像名:${harborServer}/${harborLibrary}/${gitProjectName}_${params.buildType}_${apiDokerPort}:${imageTag}"
echo "接口地址: ${apiServer}"
echo "页面地址: http://${sshServer}:${apiDokerPort}"
echo "容器端口: ${apiDokerPort}"
}
}
}
}
}