本文简单介绍了Monorepo在开发多服务应用方面的优势。以及如何使用GitLabCI/CD和Docker轻松构建、测试和部署此类应用程序。现代基于Web的应用程序通常包含多种服务。例如,后端API和前端客户端。在扩展成为问题的大型项目中,服务也可以拆分为多个微服务。在这样的项目中如何组织源代码?一种解决方案是monorepo,其中项目中的所有源代码都在同一个存储库中进行管理。另一种选择是为每个微服务创建一个存储库管理。monorepo方法允许轻松访问整个代码库,这带来了许多优点,例如易于代码重用、简化依赖管理。但是每个服务的语义版本控制和部署过程会更加复杂。我将通过一个示例项目来解释monorepo的概念及其部署。该项目是一个仅包含两个服务的Web应用程序:后端和前端。例如,后端可以是在服务器上运行并提供REST或GraphQLAPI的Node.js应用程序。前端可以是用JavaScript框架(如React或Vue.js)编写的单页应用程序,由简单的Web服务器提供给客户端。所有源代码都在monorepo中管理。我们简单项目的文件结构如下:monorepo/backend/src/Dockerfilefrontend/src/Dockerfile.git/.gitignore.gitlab-ci.yamldocker-compose.yaml在本地开发和服务器生产中,我们使用Docker容器。因此,每个服务都有一个描述其Docker镜像的Dockerfile。文件docker-compose.yaml用于在本地开发环境中配置和启动容器。可以在服务器上使用类似的文件来运行应用程序,也可以使用Kubernetes等Docker编排工具。CI/CD管道我们的目标是在每次发布新版本时自动构建、测试应用程序并将其部署到服务器(即“代码提交到GitLab”)。这包括构建和测试服务,将每个服务捆绑在Docker镜像中,并将这些镜像存储在(私有)GitLabDockerRegistry中。最后,服务器会自动收到有关新版本的通知,并触发从注册表中拉取新映像。所有这些都可以通过GitLabCI/CD实现。这是一个非常强大的工具。基本上,GitLabCI/CD管道由构建、测试和部署等几个阶段组成。该管道配置了一个名为.gitlab-ci.yaml的文件,该文件存储在我们存储库的根目录中。在monorepo的情况下,我们必须确保触发GitLabCI/CD管道的正确阶段。此外,我们通常希望仅构建、测试和部署应用程序中已更改的那些服务,而不是将所有服务合并在一起,因为这可能非常耗时。在.gitlab-ci.yaml文件中,我们为每个服务和每个阶段定义作业。为确保服务的作业仅在更改服务源代码后执行,我们可以将only/changes子句与文件夹路径的正则表达式结合使用。例如,后端服务的构建作业可以定义如下:backend_build:stage:buildonly:changes:-"backend/**/*"...脚本仅需四行代码即可为后端服务构建Docker在作业部分Image并将其推送到GitLabDockerRegistry。backend_build:...script:-dockerlogin-u$DOCKER_USER-p$ACCESS_TOKEN$CI_REGISTRY-cdbackend-dockerbuild-fDockerfile--taglatest.-dockerpushlatest...在第一行中,我们使用用户名和访问令牌Docker登录GitLab注册表,此用户名和访问令牌先前在变量名称$DOCKER_USER和$ACCESS_TOKEN中定义(在GitLab项目的设置中)。然后,我们进入backend/文件夹,运行Dockerbuild命令,最后将镜像推送到registry。我们的服务测试可以在另一个作业中执行,比如backend_test。所需的命令和脚本在很大程度上取决于我们项目的测试基础设施,但基本上,我们调用的脚本与我们在本地开发环境中使用的脚本相同。GitLabCI/CD也可以进行更复杂的测试,例如集成或端到端测试。一旦构建并存储在注册表中,服务的Docker映像就可以轻松地放入CI/CD管道中,并在测试中用作服务容器。一旦构建和测试,我们的Docker镜像就可以部署了。我们为应用程序的每个服务定义一个部署作业,它在其中登录到服务器并触发从GitLabDocker注册表中拉取新图像。总之,可以在monorepo中组织由多个服务和库组成的应用程序的源代码。尽管使用monorepo进行部署更为复杂,但只需使用一个额外的工具即可实现。GitLab就是此类工具的一个示例,它结合了存储库管理、强大的CI/CD管道和私有Docker注册表。
