在 CI/CD 中如何管理前端和后端之间的依赖关系?

2024-01-08

我将描述我的设置,以使问题不那么抽象,但它们似乎并不针对我的情况。

Context

我们有 Python-Django 后端和 VueJS 前端,每个都位于存储库中,并使用 Portainer(使用堆栈)配置和部署 Gitlab-CI。 每个存储库的生产分支中的提交都遵循以下路径:

  1. commit
  2. gitlab-ci pipeline:
    1. 构建docker镜像
    2. 测试图像(前端针对已部署的后端进行测试)
    3. 将图像标记为生产:最新
    4. 将镜像推送回 gitlab 注册表
    5. webhook portainer 中相应的服务(前端/后端)来更新部署的镜像
  3. portainer:
    1. 拉取镜像
    2. deploy

Problems

部署同步

想象一下,我们正在前端和后端进行重大更改,并且两者都将与以前的版本不兼容。因此新版本必须同时部署。

在我们当前的设置中,我们必须首先部署后端(这将破坏已部署的前端),然后部署新的前端,修复生产,但有一个“停机”期。

测试的分支依赖性

有时,当我们在前端开发分支feature-1时,必须针对后端的分支feature-1进行测试。

在我们当前的设置中,前端中的所有提交都会针对已部署的后端进行测试(为了避免在 CI 中复制后端,仅使用生产 API 地址),在这种情况下会导致错误的测试结果。

后端集成测试

当对后端进行提交时,可能会破坏前端。

目前,后端尚未针对前端进行测试(仅以另一种方式进行测试)。

可能的解决方案

对于部署同步问题,我考虑创建另一个存储库,该存储库只有一个文件指定应部署的前端和后端的版本。此存储库中的提交将导致 Portanier 的服务 Webhooks 被“卷曲”以进行更新(后端和前端)。这并不能保证同步更新(Portainer 中可能会失败并且不会回滚),但它会比当前设置更好。

我不确定应该使用什么来指定版本:提交哈希、git 标签、分支、docker 映像版本...最后一个可能避免必须重建和测试映像,但我认为映像名称和版本已固定在Portainer的堆栈定义,并且不容易自动更新。

对于分支依赖性测试,我考虑在每个存储库(前端和后端)中都有一个文件,指定要测试后端/前端的哪个分支。但是每个存储库的 CI 必须复制整个部署环境(例如,运行新的后端和前端来测试每个前端提交)。这也将允许后端集成测试。由于我们使用的是 Docker,这并不是很复杂,但是每个 CI 管道都会花费额外的时间...此外,当提交第一个存储库(前端或后端)时,它将引用另一个存储库中仍然不存在的分支存储库,并失败...

这些解决方案对我来说似乎很尴尬,特别是如果这些是 Docker 的 CI/CD 常见问题。当我们添加更多存储库时,它会变得更加丑陋。

备择方案?

感谢您的关注!

(edit:出于好奇,我当前的设置是基于此article https://medium.com/lucjuggery/even-the-smallest-side-project-deserves-its-ci-cd-pipeline-281f80f39fdf)


部署同步

想象一下,我们正在前端和后端进行重大更改,并且两者都将与以前的版本不兼容。因此新版本必须同时部署。

在我们当前的设置中,我们必须首先部署后端(这将破坏已部署的前端),然后部署新的前端,修复生产,但有一个“停机”期。

我不是 portainer 用户,但也许你可以依赖一些docker-compose.yml文件或类似的文件,收集后端和前端的版本?在这种情况下,它们可以同时更新......

确实根据肖像画/肖像画#1963 https://github.com/portainer/portainer/pull/1963 and 此文档页面 https://portainer.readthedocs.io/en/stable/templates.html?highlight=yml#type,portainer 似乎同时支持 docker-compose 和 swarm 堆栈。

此外,docker swarm 还提供了一些无需停机即可执行服务升级的功能,如中所述这个博客 https://sreeninet.wordpress.com/2017/08/15/docker-features-for-handling-containers-death-and-resurrection/#serviceupgrade,但我不知道在portainer中可以配置到什么程度。

可能的解决方案

我不确定应该使用什么来指定版本:提交哈希、git 标签、分支、docker 映像版本...最后一个可能避免必须重建和测试映像,但我认为映像名称和版本已固定在Portainer的堆栈定义,并且不容易自动更新。

虽然提交哈希是精确的标识符,但它们可能不足以方便地识别不兼容的版本。所以你可能想要依赖语义版本控制 https://semver.org/在 Git 后端存储库上使用标签(和/或分支)。

然后,您可以相应地标记相应的 Docker 镜像,如果需要,可以引入一些同义标记。例如,假设后端已经发布了版本1.0.0, 1.0.1, 1.1.0, 1.1.1, 1.2.0, 1.2.1, 1.2.2,标准做法是像这样标记 Docker 镜像:

  • project/backend:2.0.2 = project/backend:2.0 = project/backend:2
  • project/backend:2.0.1
  • project/backend:2.0.0
  • project/backend:1.1.1 = project/backend:1.1 = project/backend:1
  • project/backend:1.1.0
  • project/backend:1.0.1 = project/backend:1.0
  • project/backend:1.0.0

(如果需要,删除旧图像)

后端集成测试

目前,后端尚未针对前端进行测试(仅以另一种方式进行测试)。

好的,但我想你的方法是相当标准的(前端取决于后端,而不是相反)。

无论如何,我记得即使被测系统是前端,也可能值得实施单元测试(开发和运行成本低于集成测试),以便管道中的第一阶段快速运行这些测试在触发必要的集成测试之前进行单元测试。

测试的分支依赖性

在我们当前的设置中,前端中的所有提交都会针对已部署的后端进行测试(为了避免在 CI 中复制后端,仅使用生产 API 地址),在这种情况下会导致错误的测试结果。

这可能不够灵活:一般来说,CI/CD 假设集成测试是使用专用后端实例(“dev”服务器或“pre-prod”服务器)运行的,如果所有集成测试和系统测试都通过,则镜像部署到“prod”服务器(并进行监控等)

我从你的帖子中看到你正在使用 GitLab CI,它有一些原生 Docker 支持 https://docs.gitlab.com/ce/ci/docker/using_docker_build.html,所以也许这可以很容易地实现。

一些提示:

  • 假设后端已被修改为非向后兼容版本,并且相应的 Docker 镜像在注册表中可用(例如 GitLab CI 的镜像)。然后您可以在前端配置中更改该图像的规范(例如,替换project/backend:1 with project/backend:2或 GitLab CI 配置文件中的内容)。

  • 您的后端可能是作为 REST Web 服务实现的,在这种情况下,您可能还想在 URL 中添加版本前缀,以便当您从project/backend:1 to project/backend:2(具有不兼容的更改),如果需要,两个版本可以同时部署到 URLhttps://example.com/api/v1/… and https://example.com/api/v2/…

此外,除了只有两个带有 CI/CD 的存储库(后端分开测试,前端针对后端的相关版本进行测试)的解决方案之外,还可以考虑您首先建议的解决方案:

对于部署同步问题,我考虑创建另一个存储库,该存储库只有一个文件指定应部署的前端和后端的版本。此存储库中的提交将导致 Portanier 的服务 Webhooks 被“卷曲”以进行更新(后端和前端)。这并不能保证同步更新(Portainer 中可能会失败并且不会回滚),但它会比当前设置更好。

您可以稍微修改此方法以避免此类部署失败:您可以向第三个存储库添加一些 CI 设置,该设置仅包含docker-compose.yml文件左右,并将集成测试从前端 CI 移动到“撰写”CI…

(仅供参考,这种方法类似于此中建议的方法数字海洋教程 https://www.digitalocean.com/community/tutorials/how-to-configure-a-continuous-integration-testing-environment-with-docker-and-docker-compose-on-ubuntu-14-04#step-7-%E2%80%94-create-the-testing-environment,其中集成测试的实现要归功于一些docker-compose.test.yml file.)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 CI/CD 中如何管理前端和后端之间的依赖关系? 的相关文章

随机推荐