git,Jenkins,docker持续集成
docker的dockerfile/docker compose完成后再加入jenkins就能完成持续集成了
Jenkins篇
Jenkins创建多分支流水线任务:

配置: 代码仓库地址,登录凭证,Jenkinsfile,保存后会自动扫描分支,构建时选择要构建的分支

重点时jenkinsfile如何完成拉取代码到部署的:
先看项目结构:

dockerfile dockercompose 在docker篇已经讲了,下面看jenkinsfile
// ===================================================================== // Seata 示例项目 CI/CD 流水线:代码提交 -> 编译测试 -> 打包 -> 镜像 -> 部署 // 触发:Git push(webhook)+ pollSCM 轮询兜底 // ===================================================================== pipeline { agent any environment { // 镜像仓库地址(换成你的 Harbor / 阿里云 ACR) REGISTRY = 'harbor.example.com/seata-demo' // 镜像版本:git 短哈希 + 构建号,保证每次的IMAGE_TAG都不同,后面执行dockercompose时, //IMAGE_TAG变化的镜像才会重新运行为容器,也便于追溯与回滚 IMAGE_TAG = "${env.GIT_COMMIT ? env.GIT_COMMIT.take(7) : 'local'}-${BUILD_NUMBER}" // 需要打成镜像的可运行模块(common-api 是公共 jar,不单独成镜像) SERVICES = 'order-service storage-service account-service notify-service ' + 'tcc-order-service tcc-storage-service tcc-account-service saga-service' } options { timestamps() // 日志带时间戳 buildDiscarder(logRotator(numToKeepStr: '10')) // 只保留最近 10 次构建,省磁盘 timeout(time: 30, unit: 'MINUTES') } stages { stage('1. 拉取代码') { //从代码仓库获取最新代码 steps { checkout scm } } stage('2. 构建 Docker 镜像') { steps { script { SERVICES.split().each { module -> // SERVICES里配置了所有要构建镜像的模块 def image = "${REGISTRY}/${module}:${IMAGE_TAG}" echo "构建镜像:${image}" sh "docker build --build-arg MODULE=${module} -t ${image} ." // docker build命令作用是用dickerfile生成镜像,没有-f参数就是在上下文目录下找dockerfile,最后的 .代表上下文目录 } } } } stage('3. 推送镜像到仓库') { steps { withCredentials([usernamePassword(credentialsId: 'harbor-account', usernameVariable: 'HARBOR_USER', passwordVariable: 'HARBOR_PASS')]) { sh "docker login ${REGISTRY} -u ${HARBOR_USER} -p ${HARBOR_PASS}" } script { SERVICES.split().each { module -> sh "docker push ${REGISTRY}/${module}:${IMAGE_TAG}" } } } } stage('4. 部署到服务器') { steps { script { // 目标机需先手动 docker login 一次(或用 docker config 持久化凭据) def deployCmd = """ ssh -o StrictHostKeyChecking=no deploy@prod-server ' cd ~/app export REGISTRY="${REGISTRY}" export IMAGE_TAG="${IMAGE_TAG}" docker compose pull //从镜像仓库拉取镜像 docker compose up -d //执行dockercompose.yml文件,这里没有加--build参数,表示如果已经有镜像就不会再次打镜像,所以步骤2构建镜像里已经打了镜像,这里不会再打,dockercompose里的nacos,mysql等不变的服务也不会打镜像,这一步就完成了容器的启动 ' """ sshagent(['prod-server-ssh-key']) { sh deployCmd } } } } stage('5. 健康检查') { steps { sh 'sleep 15 && curl -f http://prod-server:8081/actuator/health || exit 1' } } } post { success { echo '发布成功' } failure { echo '发布失败,请查看控制台日志' } always { cleanWs() } } }
浙公网安备 33010602011771号