当前位置: 首页 > article >正文

第八部分-企业级实践——36. CI/CD 集成

36. CI/CD 集成1. CI/CD 概述CI/CD持续集成/持续部署与 Docker 结合可以实现代码提交后自动构建镜像、测试、部署的完整流程大幅提升开发效率和发布质量。┌─────────────────────────────────────────────────────────────┐ │ Docker CI/CD 流水线 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 代码提交 │───▶│ 自动构建 │───▶│ 自动测试 │───▶│ 镜像推送 │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ Git Docker 测试套件 镜像仓库│ │ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 部署生产 │◀───│ 部署预发 │◀───│ 镜像扫描 │◀───│ 安全检测 │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ 生产环境 预发环境 安全扫描 漏洞检测 │ │ │ └─────────────────────────────────────────────────────────────┘2. GitLab CI/CD2.1 GitLab Runner 安装# 注册 GitLab Runnerdockerrun-d--namegitlab-runner--restartalways\-v/var/run/docker.sock:/var/run/docker.sock\-v/srv/gitlab-runner/config:/etc/gitlab-runner\gitlab/gitlab-runner:latest# 注册 Runnerdockerexec-itgitlab-runner gitlab-runner register# 交互输入# GitLab URL: https://gitlab.com/# Registration token: PROJECT_TOKEN# Description: docker-runner# Tags: docker# Executor: docker# Default image: alpine:latest2.2 .gitlab-ci.yml 配置# .gitlab-ci.ymlstages:-build-test-scan-push-deployvariables:DOCKER_IMAGE:$CI_REGISTRY_IMAGE:$CI_COMMIT_SHADOCKER_LATEST:$CI_REGISTRY_IMAGE:latestDOCKER_TAG:$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG# 构建阶段build:stage:buildimage:docker:latestservices:-docker:dindscript:-docker build-t $DOCKER_IMAGE .-docker tag $DOCKER_IMAGE $DOCKER_LATESTonly:-main-develop-tags# 测试阶段test:stage:testimage:docker:latestservices:-docker:dindscript:-docker run--rm $DOCKER_IMAGE npm test-docker run--rm $DOCKER_IMAGE /app/scripts/test.shonly:-main-develop# 安全扫描scan:stage:scanimage:aquasec/trivy:latestscript:-trivy image--severity HIGH,CRITICAL--exit-code 1 $DOCKER_IMAGEonly:-main-tags# 推送镜像push:stage:pushimage:docker:latestservices:-docker:dindscript:-docker login-u $CI_REGISTRY_USER-p $CI_REGISTRY_PASSWORD $CI_REGISTRY-docker push $DOCKER_IMAGE-docker push $DOCKER_LATEST-if[-n $CI_COMMIT_TAG]; then docker tag $DOCKER_IMAGE $DOCKER_TAG; docker push $DOCKER_TAG; fionly:-main-tags# 部署到预发deploy-staging:stage:deployimage:docker:latestscript:-docker pull $DOCKER_IMAGE-docker stack deploy-c docker-compose.staging.yml--with-registry-auth myappenvironment:name:stagingurl:https://staging.example.comonly:-develop# 部署到生产deploy-production:stage:deployimage:docker:latestscript:-docker pull $DOCKER_IMAGE-docker stack deploy-c docker-compose.prod.yml--with-registry-auth myappenvironment:name:productionurl:https://example.comonly:-mainwhen:manual3. GitHub Actions3.1 Docker 镜像构建# .github/workflows/docker-build.ymlname:Docker Build and Pushon:push:branches:[main,develop]tags:[v*]pull_request:branches:[main]env:REGISTRY:ghcr.ioIMAGE_NAME:${{github.repository}}jobs:build:runs-on:ubuntu-latestpermissions:contents:readpackages:writesteps:-name:Checkout codeuses:actions/checkoutv3-name:Set up Docker Buildxuses:docker/setup-buildx-actionv2-name:Log in to GitHub Container Registryuses:docker/login-actionv2with:registry:${{env.REGISTRY}}username:${{github.actor}}password:${{secrets.GITHUB_TOKEN}}-name:Extract metadataid:metauses:docker/metadata-actionv4with:images:${{env.REGISTRY}}/${{env.IMAGE_NAME}}tags:|typeref,eventbranch typeref,eventpr typesemver,pattern{{version}} typesemver,pattern{{major}}.{{minor}} typesha-name:Build and push Docker imageuses:docker/build-push-actionv4with:context:.push:truetags:${{steps.meta.outputs.tags}}labels:${{steps.meta.outputs.labels}}cache-from:typeghacache-to:typegha,modemax-name:Scan image with Trivyuses:aquasecurity/trivy-actionmasterwith:image-ref:${{steps.meta.outputs.tags}}format:sarifoutput:trivy-results.sarifseverity:HIGH,CRITICAL-name:Upload Trivy resultsuses:github/codeql-action/upload-sarifv2with:sarif_file:trivy-results.sarif3.2 部署到服务器# .github/workflows/deploy.ymlname:Deploy to Serveron:workflow_run:workflows:[Docker Build and Push]types:-completedbranches:-mainjobs:deploy:runs-on:ubuntu-latestif:${{github.event.workflow_run.conclusion success}}steps:-name:Install SSH keyuses:shimataro/ssh-key-actionv2with:key:${{secrets.SSH_PRIVATE_KEY}}known_hosts:${{secrets.KNOWN_HOSTS}}-name:Deploy via SSHrun:|ssh -o StrictHostKeyCheckingno ${{ secrets.SERVER_USER }}${{ secrets.SERVER_HOST }} EOF cd /app docker pull ghcr.io/${{ github.repository }}:main docker-compose down docker-compose up -d docker system prune -f EOF4. Jenkins Pipeline4.1 Jenkinsfile// Jenkinsfilepipeline{agent any environment{DOCKER_REGISTRYregistry.example.comDOCKER_IMAGE${DOCKER_REGISTRY}/${JOB_NAME}:${BUILD_NUMBER}DOCKER_LATEST${DOCKER_REGISTRY}/${JOB_NAME}:latest}stages{stage(Checkout){steps{checkout scm}}stage(Build){steps{script{docker.build(${DOCKER_IMAGE})docker.image(${DOCKER_IMAGE}).tag(${DOCKER_LATEST})}}}stage(Test){steps{script{docker.image(${DOCKER_IMAGE}).inside{shnpm testshgo test ./...}}}}stage(Scan){steps{shtrivy image --severity HIGH,CRITICAL${DOCKER_IMAGE}}}stage(Push){steps{script{docker.withRegistry(https://${DOCKER_REGISTRY},registry-credentials){docker.image(${DOCKER_IMAGE}).push()docker.image(${DOCKER_LATEST}).push()}}}}stage(Deploy){steps{sh ssh deployserver cd /app \ docker pull${DOCKER_IMAGE} \ docker-compose up -d \ docker system prune -f }}}post{failure{notify.build.failure()}success{notify.build.success()}}}4.2 Docker 插件配置// Jenkins 配置// 安装 Docker Pipeline 插件// 配置 Docker 云pipeline{agent{docker{imagenode:14-alpineargs-v /var/run/docker.sock:/var/run/docker.sock}}stages{stage(Build){steps{shnpm installshnpm run build}}}}5. 自动化测试集成5.1 Docker Compose 测试# docker-compose.test.ymlversion:3.8services:sut:build:.command:npm testenvironment:-NODE_ENVtestdepends_on:-db-redisdb:image:postgres:13-alpineenvironment:-POSTGRES_DBtestdb-POSTGRES_USERtest-POSTGRES_PASSWORDtestredis:image:redis:alpine# 运行集成测试docker-compose-fdocker-compose.test.yml up --abort-on-container-exit5.2 单元测试集成# .gitlab-ci.ymltest-unit:stage:testimage:node:14-alpinescript:-npm ci-npm run test:unitcoverage:/All files[^|]*\|[^|]*\s([\d\.])/integration-test:stage:testscript:-docker-compose-f docker-compose.test.yml up--abort-on-container-exit--exit-code-from sutafter_script:-docker-compose-f docker-compose.test.yml down-v6. 多环境部署6.1 环境分离# .gitlab-ci.ymldeploy-dev:stage:deployenvironment:devscript:-docker stack deploy-c docker-compose.dev.yml myapponly:-developdeploy-staging:stage:deployenvironment:stagingscript:-docker stack deploy-c docker-compose.staging.yml myapponly:-mainwhen:manualdeploy-production:stage:deployenvironment:productionscript:-docker stack deploy-c docker-compose.prod.yml myapponly:-tagswhen:manual6.2 蓝绿部署#!/bin/bash# blue-green-deploy.sh# 获取当前环境current$(dockerservicels--filternamemyapp_web-q)if[$currentmyapp_web_blue];thennewgreenelsenewbluefi# 部署新版本dockerserviceupdate--imagemyapp:${CI_COMMIT_SHA}myapp_web_${new}# 健康检查sleep10ifcurl-fhttp://localhost:8080/health;then# 切换流量dockerserviceupdate --network-add myapp_net_${new}myapp_lbdockerserviceupdate --network-rm myapp_net_${current}myapp_lbelseechoHealth check failed!exit1fi7. 缓存优化7.1 Docker 层缓存# .gitlab-ci.ymlvariables:DOCKER_BUILDKIT:1BUILDKIT_INLINE_CACHE:1build:script:-docker pull $CI_REGISTRY_IMAGE:cache||true-docker build--cache-from $CI_REGISTRY_IMAGE:cache--tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .-docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA $CI_REGISTRY_IMAGE:cache-docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA-docker push $CI_REGISTRY_IMAGE:cache7.2 GitHub Actions 缓存-name:Cache Docker layersuses:actions/cachev3with:path:/tmp/.buildx-cachekey:${{runner.os}}-buildx-${{github.sha}}restore-keys:|${{ runner.os }}-buildx--name:Build and pushuses:docker/build-push-actionv4with:cache-from:typelocal,src/tmp/.buildx-cachecache-to:typelocal,dest/tmp/.buildx-cache-new,modemax8. 命令速查操作命令/配置GitLab Runnerdocker run -d --name gitlab-runner gitlab/gitlab-runnerGitHub Actions.github/workflows/*.ymlJenkinsfileJenkinsfile测试 Composedocker-compose -f docker-compose.test.yml up镜像缓存--cache-from9. 最佳实践✅ CI/CD 建议分层构建利用 Docker 层缓存并行测试单元测试和集成测试并行安全扫描构建后自动扫描镜像标签使用 commit SHA 作为标签环境隔离开发、测试、生产环境分离回滚机制保留历史版本通知机制构建失败及时通知❌ 避免事项在 CI 中硬编码密钥忽略缓存导致构建缓慢跳过测试和安全扫描生产环境直接使用 latest 标签10. 小结GitLab CI内置 CI/CD配置简单GitHub Actions与 GitHub 深度集成Jenkins灵活强大插件丰富自动化测试集成测试确保质量多环境部署开发/预发/生产蓝绿部署零停机发布缓存优化加速构建安全扫描是 CI 流程的重要环节

相关文章:

第八部分-企业级实践——36. CI/CD 集成

36. CI/CD 集成 1. CI/CD 概述 CI/CD(持续集成/持续部署)与 Docker 结合,可以实现代码提交后自动构建镜像、测试、部署的完整流程,大幅提升开发效率和发布质量。 ┌──────────────────────────────…...

生物 -- 神经系统(三)

1、髓鞘髓鞘是包裹在神经细胞轴突外层的绝缘膜,主要由脂质和蛋白质构成,起到加速神经信号传导、绝缘防漏电以及保护和修复神经的作用‌。你可以把它想象成电线外的绝缘皮,确保电流(即神经信号)高效、准确地传输。核心功…...

【零基础部署】Ubuntu 安装 Docker 保姆级教程

Docker 是当今最流行的容器化平台之一,它能让你把应用及其依赖打包到一个轻量级的容器中运行。无论你是想搭建开发环境、部署服务,还是学习云原生技术,Docker 都是必备技能。本文将手把手带你从零开始,在 Ubuntu 系统上完成 Docke…...

终极指南:5分钟免费解锁Cursor Pro全部功能的完整解决方案

终极指南:5分钟免费解锁Cursor Pro全部功能的完整解决方案 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached your…...

产品兼容性实战:硬件与软件设计的平衡艺术与工程策略

1. 产品兼容性:一个永恒的工程与商业困境在硬件开发,尤其是数据采集、测试测量这类领域里,产品经理和工程师们几乎每天都在面对一个看似无解的难题:新产品的功能要向前狂奔,但老用户的兼容性需求却像一根锚&#xff0c…...

终极矢量图标库完全指南:Remix Icon 3200+免费图标深度解析

终极矢量图标库完全指南:Remix Icon 3200免费图标深度解析 【免费下载链接】RemixIcon Open source neutral style icon system 项目地址: https://gitcode.com/gh_mirrors/re/RemixIcon Remix Icon 是一套开源的矢量图标库,包含超过3200个精心设…...

嵌入式处理器IP选型指南:从ARM到RISC-V的权衡与实战

1. 从一场早餐会聊起:为什么32位处理器IP依然是嵌入式开发的硬通货最近在整理资料时,翻到一篇十多年前的老新闻,说的是IP供应商CAST要在DesignCon 2012上办一场免费的早餐研讨会,主题是他们新推出的BA22 32位处理器IP核。新闻里笔…...

AI 搜索重新重视来源:内容平台的新机会不是被点击,而是被正确引用

生成式搜索刚出现时,很多内容创作者最担心的问题是:如果答案直接出现在搜索页,用户还会不会点进原文?这个担心并不多余。AI Overviews、AI Mode 和各类答案引擎,确实改变了“搜索结果页到网页”的传统路径。但现在更值…...

3分钟搞定Axure RP中文界面:全版本汉化终极指南

3分钟搞定Axure RP中文界面:全版本汉化终极指南 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文…...

Loop:Mac窗口管理的终极免费解决方案,告别杂乱桌面

Loop:Mac窗口管理的终极免费解决方案,告别杂乱桌面 【免费下载链接】Loop Window management made elegant. 项目地址: https://gitcode.com/GitHub_Trending/lo/Loop 你是否曾为Mac上杂乱的窗口而烦恼?当多个应用同时打开时&#xff…...

百度网盘Mac版加速插件:突破下载限制的实用方案

百度网盘Mac版加速插件:突破下载限制的实用方案 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 对于经常使用百度网盘的Mac用户来说&#x…...

AI编程助手与代码质量守护:Trunk Cursor插件实战指南

1. 项目概述:当AI编程助手遇上代码质量守护者如果你和我一样,日常重度依赖Cursor这类AI编程助手来加速开发,那么你一定也遇到过类似的困扰:AI生成的代码片段虽然功能上“能用”,但在代码风格、格式一致性、甚至是潜在的…...

Erupt 七年最有诚意升级:官网、文档、脚手架更新,迈向工业级开源生态!

一、写在前面:为什么这次更新值得你重新认识 Erupt?过去几年,Erupt 一直被打上“功能强但太朴素”的标签。注解驱动、AI 模块、多 UI 模板、Cloud 集群、AI Agent,内核卷到飞起,但官网、文档、脚手架这“门面三件套”始…...

RevokeMsgPatcher实战指南:Windows微信QQ防撤回的终极秘籍

RevokeMsgPatcher实战指南:Windows微信QQ防撤回的终极秘籍 【免费下载链接】RevokeMsgPatcher :trollface: A hex editor for WeChat/QQ/TIM - PC版微信/QQ/TIM防撤回补丁(我已经看到了,撤回也没用了) 项目地址: https://gitcod…...

声明式数据转换利器:Refiner 实战指南与架构集成

1. 项目概述与核心价值最近在折腾一个老项目的数据清洗和转换,被一堆格式混乱、结构不一的JSON文件搞得焦头烂额。手动写脚本处理吧,每次需求一变就得重写,维护成本太高;用现成的ETL工具吧,又觉得过于笨重,…...

Python 3.14.5 发布:多项改进,垃圾回收器回滚,还有这些新特性!

Python 3.14.5 发布Python 3.14.5 现已发布,这是 3.14 的第五个维护版本。自 3.14.4 以来,包含约 154 项错误修复、构建改进和文档更改。垃圾回收器回滚值得注意的是,Python 3.14.5 中的垃圾回收器 (GC) 发生了变化。由于一些原因&#xff0c…...

手机号到QQ号查询技术实现原理与TEA加密通信架构解析

手机号到QQ号查询技术实现原理与TEA加密通信架构解析 【免费下载链接】phone2qq 项目地址: https://gitcode.com/gh_mirrors/ph/phone2qq phone2qq是一个基于Python实现的逆向工程工具,通过分析腾讯QQ客户端的通信协议,实现了通过手机号查询对应…...

从Kaggle竞赛到现实应用:聊聊ResNet18在驾驶安全监控中的潜力与局限

从Kaggle竞赛到现实应用:ResNet18在驾驶安全监控中的潜力与局限 当计算机视觉技术走出实验室,真正进入驾驶安全监控这样的关键场景时,我们需要思考的远不止模型在测试集上的准确率。ResNet18作为轻量级深度网络的代表,其在Kaggle竞…...

3步解锁网易云音乐NCM加密文件:ncmdumpGUI图形化工具完全指南

3步解锁网易云音乐NCM加密文件:ncmdumpGUI图形化工具完全指南 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否在网易云音乐下载了喜欢的歌曲…...

AI编码助手配置框架:六层缰绳架构实现团队规范与上下文持久化

1. 项目概述:为什么你的AI编码助手总像个“健忘的实习生”? 如果你和我一样,已经深度使用Claude Code、Cursor这类AI编码助手超过半年,那你一定经历过这种“血压升高”的时刻:明明昨天刚跟它详细解释过项目的架构规范…...

利用Taotoken模型广场为内容生成应用挑选合适模型

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 利用Taotoken模型广场为内容生成应用挑选合适模型 对于开发内容生成类应用的团队而言,选择合适的模型是项目成功的关键…...

Avogadro 2:开源分子可视化库的终极技术解析

Avogadro 2:开源分子可视化库的终极技术解析 【免费下载链接】avogadrolibs Avogadro libraries provide 3D rendering, visualization, analysis and data processing useful in computational chemistry, molecular modeling, bioinformatics, materials science,…...

连接器选型五大雷区:从故障数据到设计落地的实战手册

许多硬件团队的失效分析报告显示,连接器引发的现场故障占比长期居高不下,且症状极其隐蔽——间歇性黑屏、信号丢包、热插拔烧毁……这些问题往往在原型测试阶段难以复现,直到批量出货后才集中爆发。本文从电源、高速信号、射频三类典型应用出…...

面向非技术人员的AI智能体实战:零代码自动化工作流构建指南

1. 项目概述:面向非工程师的AI智能体实战训练营如果你是一名市场、销售、运营或行政人员,每天被重复性的文档处理、数据分析、内容制作和跨平台沟通所淹没,看着工程师同事用代码自动化一切,自己却只能手动操作,那么你很…...

为OpenClaw智能体工作流配置Taotoken作为稳定后端API

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 为OpenClaw智能体工作流配置Taotoken作为稳定后端API OpenClaw是一个用于构建智能体工作流的流行框架,它允许开发者通过…...

ModuleNotFoundError: No module named ‘ui_form‘

问题描述:在QT CREATER创建一个新的python QT项目后,若无法直接编译而是报错如下:解决办法: 在该项目的目录下输入cmd,打开命令行窗口——然后输入pyside6-uic form.ui -o ui_form.py 运行即可正常编译 (若…...

终极指南:5分钟让Illustrator批量替换效率提升10倍

终极指南:5分钟让Illustrator批量替换效率提升10倍 【免费下载链接】illustrator-scripts Adobe Illustrator scripts 项目地址: https://gitcode.com/gh_mirrors/il/illustrator-scripts 还在为Adobe Illustrator中繁琐的批量替换工作而烦恼吗?&…...

终极指南:轻松突破Cursor Pro限制,实现永久免费使用

终极指南:轻松突破Cursor Pro限制,实现永久免费使用 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached…...

ComfyUI-FramePackWrapper终极指南:8GB显存玩转高质量AI视频生成

ComfyUI-FramePackWrapper终极指南:8GB显存玩转高质量AI视频生成 【免费下载链接】ComfyUI-FramePackWrapper 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-FramePackWrapper 想要在有限硬件条件下实现专业级AI视频生成吗?ComfyUI-Fram…...

ChromaControl终极指南:如何实现多品牌RGB设备统一灯光控制

ChromaControl终极指南:如何实现多品牌RGB设备统一灯光控制 【免费下载链接】ChromaControl 3rd party device lighting support for Razer Synapse. 项目地址: https://gitcode.com/gh_mirrors/ch/ChromaControl 你是否曾为不同品牌的RGB设备需要安装多个控…...