13-自动化CI/CD流水线:代码提交→编译→打包→镜像构建自动流程

发布时间:2026/8/13 0:15:43
13-自动化CI/CD流水线:代码提交→编译→打包→镜像构建自动流程 13-自动化CI/CD流水线代码提交→编译→打包→镜像构建自动流程一、什么是CI/CD先搞懂概念再动手很多新手一上来就配流水线配了半天不知道自己在配啥。咱们先把概念捋清楚。CIContinuous Integration持续集成开发人员把代码推送到仓库后自动触发编译、单元测试、代码质量检查。核心目的是——尽早发现问题别等到上线前一天才发现代码跑不起来。CDContinuous Delivery/Deployment持续交付/部署在CI的基础上把编译好的产物自动打包、构建镜像、推送到仓库甚至自动部署到测试/生产环境。一句话总结CI管编译测试CD管打包部署。两者串联起来就是一条从代码提交到上线的自动化流水线。二、为什么我们需要CI/CD在智慧农业和无人售货柜的项目中后端有十几个微服务Java SpringBoot设备端有嵌入式固件瑞芯微/STM32前端有安卓APP。如果没有CI/CD程序员手动mvn package手动docker build手动docker push——十个服务能搞一下午某个同事忘了推镜像测试环境跑的还是上周的代码排查半天上线时手忙脚乱人为操作出错率极高上了CI/CD之后git push 一敲剩下的事交给机器。这就是工程化的魅力。三、GitLab CI流水线实战我们以GitLab CI为例GitHub Actions原理类似搭建一条完整的流水线。3.1 核心概念速览概念说明Runner执行流水线的机器物理机/容器需要注册到GitLabPipeline一条完整的流水线包含多个StageStage流水线的阶段如 build → test → package → deployJobStage中的具体任务同一Stage的Job并行执行3.2 .gitlab-ci.yml 完整配置示例在项目根目录创建.gitlab-ci.yml文件# 定义阶段顺序前一个阶段全部成功才会执行下一个stages:-build-test-package-deploy# 全局变量variables:MAVEN_OPTS:-Dmaven.repo.local.m2/repositoryIMAGE_REGISTRY:registry.cn-shenzhen.aliyuncs.comIMAGE_NAMESPACE:alspd/smart-agri# 编译阶段 build-job:stage:buildimage:maven:3.8-openjdk-8script:-echo 开始编译 $CI_PROJECT_NAME -mvn clean compile-DskipTests-echo 编译完成产物路径target/artifacts:paths:-target/*.jarexpire_in:1 hourrules:-if:$CI_COMMIT_BRANCH develop||$CI_COMMIT_BRANCH main# 单元测试阶段 test-job:stage:testimage:maven:3.8-openjdk-8script:-echo 执行单元测试 -mvn test-echo 测试通过率统计-cat target/site/jacoco/index.html|grep-oP Total.*?([0-9]%)|tail-1rules:-if:$CI_COMMIT_BRANCH develop# Docker镜像构建与推送 package-job:stage:packageimage:docker:20.10services:-docker:20.10-dindscript:-echo 构建Docker镜像 # 登录镜像仓库-docker login-u $CI_REGISTRY_USER-p $CI_REGISTRY_PASSWORD $IMAGE_REGISTRY# 构建镜像标签包含分支名commit短hash时间戳-IMAGE_TAG$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-$(date %Y%m%d%H%M)-docker build-t $IMAGE_REGISTRY/$IMAGE_NAMESPACE/$CI_PROJECT_NAME:$IMAGE_TAG .-docker push $IMAGE_REGISTRY/$IMAGE_NAMESPACE/$CI_PROJECT_NAME:$IMAGE_TAG-echo 镜像推送成功$IMAGE_REGISTRY/$IMAGE_NAMESPACE/$CI_PROJECT_NAME:$IMAGE_TAG# 把镜像tag写入文件供下游阶段使用-echo $IMAGE_TAGimage-tag.txtartifacts:paths:-image-tag.txtexpire_in:1 dayrules:-if:$CI_COMMIT_BRANCH develop||$CI_COMMIT_BRANCH main# 部署到测试环境 deploy-test-job:stage:deployimage:alpine:latestbefore_script:-apk add--no-cache openssh-clientscript:-echo 部署到测试环境 -IMAGE_TAG$(cat image-tag.txt)# 通过SSH远程执行部署脚本-ssh-o StrictHostKeyCheckingno deploy192.168.1.100 docker pull $IMAGE_REGISTRY/$IMAGE_NAMESPACE/$CI_PROJECT_NAME:$IMAGE_TAGdocker stop $CI_PROJECT_NAME||truedocker rm $CI_PROJECT_NAME||truedocker run-d--name $CI_PROJECT_NAME--network agri-net-p 8080:8080-e SPRING_PROFILES_ACTIVEtest $IMAGE_REGISTRY/$IMAGE_NAMESPACE/$CI_PROJECT_NAME:$IMAGE_TAG-echo 部署完成rules:-if:$CI_COMMIT_BRANCH develop3.3 关键配置解读1artifacts产物传递build-job编译出来的 jar 包通过artifacts传递给下游Job。如果不配每个Job都是独立容器编译产物拿不到。2rules条件触发rules:-if:$CI_COMMIT_BRANCH develop只有推送到develop分支才触发完整流水线。推到feature/xxx分支只编译不部署避免每个功能分支都污染测试环境。3镜像标签策略IMAGE_TAG$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-$(date%Y%m%d%H%M)# 示例develop-a3f5c2e1-202608071430分支名 commit短hash 时间戳既能追溯代码版本又能区分构建时间。这个标签规范在下一篇会详细展开。四、Dockerfile 配套写法流水线里调了docker build对应的 Dockerfile 也得跟上# 多阶段构建减小最终镜像体积 FROM maven:3.8-openjdk-8 AS builder WORKDIR /build COPY pom.xml . RUN mvn dependency:go-offline # 先下依赖利用Docker缓存层 COPY src/ ./src/ RUN mvn clean package -DskipTests FROM openjdk:8-jre-slim WORKDIR /app COPY --frombuilder /build/target/*.jar app.jar # 健康检查K8s就绪探针会用到 HEALTHCHECK --interval30s --timeout3s \ CMD curl -f http://localhost:8080/actuator/health || exit 1 EXPOSE 8080 ENTRYPOINT [java, -jar, app.jar]多阶段构建的好处最终镜像只包含JRE和jar包不含Maven和源码体积从800MB降到180MB左右。在工控设备上部署时小镜像就是快速度。五、GitHub Actions 简版对照如果你用的是GitHub Actions逻辑完全一样换套语法name:CI/CD Pipelineon:push:branches:[develop,main]jobs:build:runs-on:ubuntu-lateststeps:-uses:actions/checkoutv3-uses:actions/setup-javav3with:java-version:8distribution:temurin-name:Maven Buildrun:mvn clean package-DskipTests-name:Build Push Docker Imagerun:|docker login -u ${{ secrets.REGISTRY_USER }} -p ${{ secrets.REGISTRY_PASS }} registry.cn-shenzhen.aliyuncs.com docker build -t registry.cn-shenzhen.aliyuncs.com/alspd/smart-agri/${{ github.event.repository.name }}:${{ github.sha }} . docker push registry.cn-shenzhen.aliyuncs.com/alspd/smart-agri/${{ github.event.repository.name }}:${{ github.sha }}六、流水线提速技巧实际项目中流水线跑10分钟以上很常见这里列几个优化点Maven依赖缓存把.m2/repository缓存到Runner第二次构建省去下载依赖的时间Docker层缓存Dockerfile中先COPY pom.xml再RUN mvn dependency:go-offline依赖不变时这层直接命中缓存并行Job把单元测试和代码质量扫描SonarQube放到同一个Stage并行执行按需触发只有src/目录变更时才触发编译文档改动不浪费CI资源# 只在源码变更时触发编译rules:-if:$CI_COMMIT_BRANCH developchanges:-src/**-pom.xml七、小结CI/CD的本质是把人的重复劳动交给机器。代码提交后自动编译、测试、打包、构建镜像、推送仓库、部署——一气呵成。配置好之后开发人员只需要关心写代码部署的事全自动。下一篇我们会深入Docker镜像版本管理讲清楚标签规范、版本留存策略和镜像清理——别让镜像仓库变成垃圾场。