news 2026/10/2 2:09:24

AWS DevOps 实战:使用 CodePipeline 与 CodeBuild 为 Python 应用搭建完整 CI 流水线

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AWS DevOps 实战:使用 CodePipeline 与 CodeBuild 为 Python 应用搭建完整 CI 流水线
  • 教程
  • 文档
  • DevOps

【免费下载链接】aws-devops-zero-to-hero

AWS zero to hero repo for devops engineers to learn AWS in 30 Days. This repo includes projects, presentations, interview questions and real time examples.

项目地址:https://gitcode.com/GitHub_Trending/aw/aws-devops-zero-to-hero
点击查看免费下载

本文基于 aws-devops-zero-to-hero 项目 Day 14 的实战指南,系统讲解如何从零搭建一条以 GitHub 为代码源、以 AWS CodePipeline 编排、以 AWS CodeBuild 执行构建与测试的完整持续集成(CI)流水线。文章将完整覆盖仓库初始化、流水线创建、构建项目配置与变更触发全流程,并结合仓库内 simple-python-app 的 Flask 示例应用及其 buildspec.yml、Dockerfile 等真实文件,深入剖析 CI 配置背后的构建原理与落地细节。读完本文,你将能独立在自己的 AWS 环境中复刻一条"代码推送即自动构建测试"的 CI 流水线。

一、整体思路:一条 CI 流水线由哪些环节组成

在进入控制台操作之前,先建立整体认知。Day 14 的持续集成演示围绕一条典型流水线展开,涉及三个核心角色:

  • GitHub 仓库:代码的唯一事实来源,承载 Python 应用的源码与构建配置。
  • AWS CodePipeline:全托管式持续交付编排服务,负责监听代码变更,并按阶段顺序驱动 Source(源码获取)、Build(构建测试)、Deploy(部署)各环节。
  • AWS CodeBuild:全托管式构建服务,按 buildspec.yml 中声明的命令完成依赖安装、测试执行、镜像构建与产物产出。

这条流水线的核心闭环是:开发者将代码变更推送到 GitHub 指定分支 → CodePipeline 检测到变更 → 拉取最新源码 → 交给 CodeBuild 执行构建与测试 → 产出构建产物(并可继续触发部署)。在整个 aws-devops-zero-to-hero 30 天课程体系中,Day 14 的 CI 演示处于承上启下的位置——它承接 Day 13 的 CodePipeline 编排知识,并为 Day 20 的 ECR、Day 21 的 ECS 等容器化部署场景打下"自动化构建"的基础。

二、第一步:搭建 GitHub 代码仓库

构建 CI 流水线的前提,是先把应用代码托管到版本控制系统。如果已有仓库可以直接跳过本步,否则按以下步骤在 GitHub 上创建新仓库:

  1. 访问 github.com 并登录账号;
  2. 点击右上角 "+" 按钮,选择 "New repository";
  3. 为仓库填写名称(如simple-python-app)和可选的描述信息;
  4. 根据需求选择合适的可见性(Public 或 Private)——注意后续 CodePipeline 连接 GitHub 时需要授权,私有仓库同样支持;
  5. 勾选 "Initialize this repository with a README" 初始化仓库;
  6. 点击 "Create repository" 完成创建。

仓库创建完成后,即可将本地代码推送到远端。本仓库中day-14目录下的示例应用就是一个理想的最小化 CI 实验对象,其源码文件构成了 CI 流水线要处理的"输入":

  • app.py:基于 Flask 的最小 Web 应用,暴露/路由并返回Hello, world!;
  • requirements.txt:声明依赖flask;
  • Dockerfile:定义应用容器镜像的构建方式。

其中 app.py 的完整源码如下,它将被 CodeBuild 拉取并作为构建对象:

from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return 'Hello, world!' if __name__ == '__main__': app.run()

从该文件可以看出:这是一个无状态、单路由的 Flask 应用,非常适合用来验证"代码变更 → 自动构建"的 CI 链路——例如将返回字符串改为Hello, CI!,推送后即可在 CodeBuild 日志中观察构建重新触发。

三、第二步:创建 AWS CodePipeline 流水线

CodePipeline 是整个 CI 流程的"导演",负责把源代码变更按阶段有序地送给构建与部署服务。按以下步骤在 AWS 管理控制台中创建流水线:

  1. 登录 AWS 管理控制台,进入AWS CodePipeline服务;
  2. 点击"Create pipeline"按钮;
  3. 为流水线命名(如python-app-ci-pipeline),点击"Next";
  4. Source 阶段:选择"GitHub"作为源提供方,授权 AWS CodePipeline 连接你的 GitHub 账号,选择目标仓库,并指定要监听的分支;
  5. Build 阶段:选择"AWS CodeBuild"作为构建提供方;
  6. 点击"Create project"新建 CodeBuild 构建项目(细节见下一节),保存后返回 CodePipeline 继续;
  7. 配置后续阶段(如Deploy 阶段),可选用 AWS Elastic Beanstalk 或其他适合应用的部署方式;本演示以 CI 为主,若暂时不需要自动部署,也可以让流水线止步于 Build 阶段;
  8. 审查整个流水线配置,点击"Create pipeline"完成创建。

需要说明的是,Console 向导式的创建方式适合首次上手;对于生产环境,更推荐用 AWS CloudFormation 或 Terraform 以代码方式定义流水线,便于版本化管理——这属于 Day 11 与 Day 24 课程内容的延伸。本仓库的 main.tf、provider.tf 等文件即展示了类似的 IaC 实践思路。

四、第三步:配置 AWS CodeBuild 构建项目

CodeBuild 是流水线的"执行者",负责真正跑起构建。在 CodePipeline 的 Build 阶段点击 "Create project" 后,需要完成以下配置:

  1. 为构建项目命名(如python-app-build);
  2. Source 提供方选择"AWS CodePipeline",表示构建输入由流水线统一注入,而不是由 CodeBuild 独立拉取 GitHub 代码——这是与流水线集成时的标准配置;
  3. 选择该流水线作为来源;
  4. 配置构建环境(Environment):选择操作系统(本应用场景为 Linux)、运行时(Python)以及计算资源规格,应与应用实际需要匹配;
  5. 配置Buildspec:CodeBuild 默认会在源码根目录查找buildspec.yml作为构建说明书;也可以在控制台直接以编辑器形式内嵌构建命令;
  6. 配置构建命令(Build commands):典型内容包括安装依赖、运行测试,可按应用实际需求自定义;
  7. 配置Artifacts(构建产物):声明要生成的构建输出,供后续部署阶段使用;
  8. 审查配置后点击"Create build project"创建项目。

4.1 从 buildspec.yml 看 CodeBuild 的实际执行逻辑

控制台中的各项配置最终都会落到构建说明书上。仓库中的 buildspec.yml 是理解 CodeBuild 执行逻辑的关键文件,其完整内容如下:

version: 0.2 env: parameter-store: DOCKER_REGISTRY_USERNAME: /myapp/docker-credentials/username DOCKER_REGISTRY_PASSWORD: /myapp/docker-credentials/password DOCKER_REGISTRY_URL: /myapp/docker-registry/url phases: install: runtime-versions: python: 3.11 pre_build: commands: - echo "Installing dependencies..." - pip install -r day-13/simple-python-app/requirements.txt build: commands: - echo "Running tests..." - cd day-13/simple-python-app/ - echo "Building Docker image..." - echo "$DOCKER_REGISTRY_PASSWORD" | docker login -u "$DOCKER_REGISTRY_USERNAME" --password-stdin "$DOCKER_REGISTRY_URL" - docker build -t "$DOCKER_REGISTRY_URL/$DOCKER_REGISTRY_USERNAME/simple-python-flask-app:latest" . - docker push "$DOCKER_REGISTRY_URL/$DOCKER_REGISTRY_USERNAME/simple-python-flask-app:latest" post_build: commands: - echo "Build completed successfully!" artifacts: files: - '**/*' base-directory: ../simple-python-app

逐段拆解这份构建说明书,可以清晰看到 CodeBuild 的分阶段执行模型:

  • version: 0.2:声明 Buildspec 规范版本,0.2 是当前主流版本,支持参数存储引用、运行时版本指定等特性;
  • env.parameter-store:通过 AWS Systems Manager Parameter Store 安全注入敏感配置。/myapp/docker-credentials/username、/myapp/docker-credentials/password、/myapp/docker-registry/url三个路径分别存放 Docker Registry 的用户名、密码与地址。这避免了在 buildspec 中硬编码密钥,CI 过程中这些值会以环境变量形式注入到构建容器;
  • phases:CodeBuild 的核心执行阶段,按顺序依次运行——
    • install:声明构建环境运行时版本,此处固定为python: 3.11;
    • pre_build:构建前的准备工作,安装requirements.txt中的依赖;
    • build:主构建阶段,先输出测试日志占位,再切换进应用目录,完成docker login、docker build与docker push,把 Flask 应用打包为simple-python-flask-app:latest镜像并推送至 Registry;
    • post_build:收尾阶段,输出构建成功标志;
  • artifacts:声明构建产物——files: '**/*'收集全部文件,base-directory指定产物根目录。这些产物会作为流水线后续部署阶段的输入。

4.2 补充解读:buildspec 中的路径说明

值得注意的细节是,该 buildspec 中依赖安装与构建命令引用了day-13/simple-python-app/路径,而 artifacts 的base-directory又指向../simple-python-app。这反映了该演示在仓库演进过程中的历史路径差异——在实际复用时,请以你仓库中应用的实际目录结构为准,保持pre_build、build命令的cd目录与artifacts.base-directory三处路径一致,否则 CodeBuild 会因找不到requirements.txt或 Dockerfile 而构建失败。

4.3 从 Dockerfile 理解镜像构建的目标产物

build阶段执行的docker build依赖应用目录中的 Dockerfile,其内容如下:

# Base image FROM python:3.8 # Set the working directory inside the container WORKDIR /app # Copy the requirements file COPY requirements.txt . # Install the project dependencies RUN pip install -r requirements.txt # Copy the application code into the container COPY . . # Expose the port the Flask application will be listening on EXPOSE 5000 # Set environment variables, if necessary # ENV MY_ENV_VAR=value # Run the Flask application CMD ["python", "app.py"]

这份 Dockerfile 展示了容器化的经典分层策略:先拷贝requirements.txt并安装依赖(充分利用镜像层缓存,避免源码变更后依赖重复安装),再拷贝应用代码,声明 5000 端口并指定启动命令。它对应 CI 产物形态——每次代码变更触发构建后,CodeBuild 都会产出新的simple-python-flask-app:latest镜像并推送,为 Day 20(ECR)与 Day 21(ECS)的容器部署流水线直接提供输入。

4.4 与 CodeDeploy 的衔接:appspec.yml 的定位

虽然 Day 14 演示聚焦 CI,但仓库中同时提供了 appspec.yml(根目录还有一份等效的 appspec.yml),展示部署阶段的雏形:

version: 0.0 os: linux hooks: ApplicationStop: - location: scripts/stop_container.sh timeout: 300 runas: root AfterInstall: - location: scripts/start_container.sh timeout: 300 runas: root

这份 AppSpec 文件定义了 CodeDeploy 在部署时的生命周期钩子:ApplicationStop阶段执行 scripts/stop_container.sh 停止旧容器,AfterInstall阶段执行 scripts/start_container.sh 从 Docker Hub 拉取abhishekf5/simple-python-flask-app镜像并启动容器(docker run -d -p 5000:5000)。它可以在将来为流水线追加 Deploy 阶段,把 CodeBuild 的构建产物真正部署到 EC2 实例上,从而把 CI 扩展为完整的 CI/CD——这正是 Day 15 课程的主题。

五、第四步:触发 CI 流程并验证

流水线配置完成后,验证环节是整个 CI 演示的高潮部分:

  1. 回到 GitHub 仓库,对 Python 应用源码做一次修改——可以是 bug 修复、新功能,或任何想引入的变更(例如修改 app.py 中hello()的返回值);
  2. 将变更Commit 并 Push到 CodePipeline 中配置的分支;
  3. 打开 AWS CodePipeline 控制台并进入该流水线;
  4. 观察流水线是否在检测到仓库变更后自动启动——GitHub 的 Webhook 事件会在毫秒级内触发流水线执行;
  5. 之后无需人工干预:CodePipeline 自动拉取最新代码、调用 CodeBuild 执行构建测试,若配置了部署阶段则继续自动部署。

5.1 验证点与常见排查思路

搭建完成后建议从三个角度验证 CI 是否真正生效:

  • 构建日志:在 CodeBuild 构建任务详情页查看各 phase 日志,pre_build阶段应出现依赖安装输出,build阶段应出现docker build与docker push成功记录,post_build阶段应出现Build completed successfully!;
  • 阶段状态:CodePipeline 控制台上 Source、Build 阶段应依次变为绿色 Success 状态;
  • 镜像产物:登录 Docker Registry(如 ECR 或 Docker Hub),确认simple-python-flask-app:latest标签已被更新为最新构建产物。

若构建失败,优先检查三类问题:buildspec.yml中路径与仓库实际目录是否一致、Parameter Store 中的三个凭据路径是否正确预置、构建环境是否具备 Docker 权限(构建容器需运行 Docker-in-Docker 或特权模式才能执行docker build)。

六、总结:Day 14 在 DevOps 技能树中的位置

通过本演示,你完成了一条完整的持续集成闭环:GitHub 承载代码 → CodePipeline 编排流程 → CodeBuild 按 buildspec 执行依赖安装、测试与镜像构建 → 产物(容器镜像)自动推送。这一能力是后续所有自动化部署场景的基石。

从 aws-devops-zero-to-hero 项目整体课程线来看,Day 14 与相邻课程形成了清晰的递进关系:

  • Day 13 的 CodePipeline 提供了流水线编排的基础认知;
  • Day 14(本文)把重点落到 CodeBuild 的构建配置与 buildspec 实践;
  • Day 15 的 CodeDeploy 将借助本仓库的 appspec.yml 与 scripts 完成"构建之后如何部署"的闭环;
  • Day 20/21 的 ECR 与 ECS 将消费本演示产出的simple-python-flask-app:latest镜像,实现容器化的端到端交付。

如果你希望在本演示基础上进一步深入,可以沿两条路线扩展:其一,为流水线追加 Deploy 阶段并用 appspec.yml 驱动 CodeDeploy;其二,将buildspec.yml中的镜像仓库地址替换为 AWS ECR(结合 Day 20 内容),让构建产物沉淀到 AWS 托管镜像仓库中。理解 buildspec 的阶段模型与参数注入机制后,这些扩展都是对现有配置的低成本改造。

  • 教程
  • 文档
  • DevOps

【免费下载链接】aws-devops-zero-to-hero

AWS zero to hero repo for devops engineers to learn AWS in 30 Days. This repo includes projects, presentations, interview questions and real time examples.

项目地址:https://gitcode.com/GitHub_Trending/aw/aws-devops-zero-to-hero
点击查看免费下载
上一篇:7-Taskbar-Tweaker深度定制指南:解锁Windows任务栏终极个性化配置
下一篇:PowerToys中文完整汉化版:如何快速掌握这款终极Windows效率工具

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 2:09:06

缓存与数据库一致性实战:从Cache Aside到延迟双删

你翻过线上日志没?我翻过。凌晨两点,用户明明支付成功了,状态却一直显示“未支付”,后台查订单数据库里状态明明是“已支付”,但用户页面读到的还是旧值。最后定位出来,不是支付接口的问题,是缓…

作者头像 李华
网站建设 2026/10/2 2:07:40

Leptonica+Tesseract+OpenCV 资源库:OCR 环境搭建与避坑指南

简介:这份资源面向从事图像处理与OCR开发的工程师、科研人员及AI应用开发者,解决leptonica、tesseract、opencv三大库版本匹配与编译配置繁琐的问题。包内集成leptonica 1.76.0、tesseract 5.0.0与opencv 4.0.0,可直接调用,省去自…

作者头像 李华
网站建设 2026/10/2 2:07:15

Flink实时计算音乐专辑热度:从Kafka到MySQL端到端实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/2 2:04:51

Linux进程地址空间详解:虚拟内存、页表与写时复制

1. 从一道面试题说起:进程地址空间到底是什么带过几个刚接触 Linux 的同事,发现大家最容易在“进程地址空间”这个概念上卡住。你以为它是内存条里的物理地址?其实不是。进程地址空间更像是操作系统发给每个进程的一张“虚拟地图”&#xff0…

作者头像 李华