问题描述
正在处理一个项目,该项目由多个不同语言的服务组成(React webapp、Scala后端、Python等)。目前,他将每个服务分别放在Github上的不同代码库中,并使用CircleCI进行构建。
有些人似乎推崇单一代码库(monorepo)。由于计划将代码迁移到Gitlab上,用户想借此机会了解如何将其转换为单一代码库。他有三个问题:
1. 如果我将所有服务放在同一个项目中(Gitlab中称为项目),能否让CI/CD系统独立构建每个组件?
2. 我能否让Gitlab将多个镜像发布到我的容器注册表中?
3. 假设我对一个服务进行了更改,并希望在部署之前确保它与其他服务正常工作,如何设置与其他服务交互的集成测试,以确保提交成功?
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
单一代码库(monorepo)的好处在于消除了多个项目之间的技术限制。但是,这也会在代码库中引入其他复杂性(命名约定、跨团队依赖、合并冲突增加等)。虽然我没有使用CircleCI的经验,但我可以根据我使用过的其他CI工具提供一些建议。
1. 我认为你完全可以做到。在你的CI/CD系统中,不再引用各个源代码库,而是使用主要的单一代码库作为源代码库,然后引用其中的特定项目目录。
2. 根据GitLab的版本9.1,似乎是支持的。
3. 在我看来,这不应该在提交时发生。你可以这样做,但我认为这会显著减慢你的开发速度,并且如果有很多提交,会消耗大量资源。需要考虑的两个关键点是:
– 在每次生产发布之前,应对基础架构中的所有项目运行完整的套件测试。这是确保所有项目依赖关系不会破坏的唯一方法。
– 测试/配置必须并行运行。通过这样做,你的完整代码库测试速度将取决于代码库中最长的测试/配置时间。(作为副作用,这强调了加快最慢测试的重要性)
方案2
使用脚本或工具来管理容器的启动顺序可能会增加复杂性,并且需要确保容器A和容器B之间的依赖关系正确设置。
另一种方法是编写脚本或使用工具来控制容器的运行顺序。你可以使用docker run
命令来手动控制容器的启动顺序,或者使用一些第三方工具来管理容器的依赖关系。
以下是一个简单的bash脚本示例,可以在容器A启动后启动容器B:
#!/bin/bash
# 启动容器A
docker run -d --name container_a your_image_a
# 等待容器A完全启动
while ! docker exec container_a echo "Container A is ready"; do
sleep 1
done
# 启动容器B
docker run -d --name container_b your_image_b
在这个示例中,我们首先使用docker run
命令启动容器A,并将其命名为container_a
。然后,使用一个循环来等待容器A完全启动(这里是通过在容器内运行echo
命令来测试)。一旦容器A就绪,我们再使用docker run
命令启动容器B,并将其命名为container_b
。
以上是两种解决方案,你可以根据自己的需求选择适合的方法。