Operations 7 min read

Using a Monorepo with GitLab CI/CD and Docker for Multi‑Service Applications

This article explains the benefits of a monorepo for multi‑service web applications and demonstrates how to set up GitLab CI/CD pipelines and Docker containers to build, test, and deploy backend and frontend services efficiently.

DevOps Cloud Academy
DevOps Cloud Academy
DevOps Cloud Academy
Using a Monorepo with GitLab CI/CD and Docker for Multi‑Service Applications

This article briefly introduces the advantages of using a monorepo for developing multi‑service applications and shows how to easily build, test, and deploy such applications with GitLab CI/CD and Docker.

Modern web applications typically consist of several services, such as a backend API and a frontend client. In large projects, these services may be split into multiple micro‑services, raising the question of how to organize the source code. One solution is a monorepo, where all source code lives in a single repository; the alternative is to maintain a separate repository for each micro‑service.

The monorepo approach provides easy access to the entire codebase, enabling code reuse and simplifying dependency management, although it can make semantic versioning and deployment more complex for each service.

To illustrate the concept, a simple example project is presented that contains two services: a backend Node.js application exposing a REST or GraphQL API, and a frontend single‑page application built with a JavaScript framework such as React or Vue.js. All source files are stored in a single monorepo with the following structure:

monorepo/
backend/
src/
Dockerfile
frontend/
src/
Dockerfile
.git/
.gitignore
.gitlab-ci.yaml
docker-compose.yaml

Both services are containerized with Docker for local development and production. Each service has its own Dockerfile, and a docker-compose.yaml file is used to spin up the containers locally. The same setup can be adapted for orchestration tools like Kubernetes.

The CI/CD pipeline aims to automatically build, test, and deploy the application whenever a new version is pushed to GitLab. The pipeline consists of stages such as build , test , and deploy , defined in a .gitlab-ci.yaml file at the repository root. For a monorepo, it is important to trigger only the jobs related to services whose source code has changed, to avoid unnecessary work.

An example of a backend build job that runs only when files under backend/ change:

backend_build:
stage: build
only:
changes:
- "backend/**/*"
...

The corresponding script for this job contains just four commands to build the backend Docker image and push it to the GitLab Docker Registry:

backend_build:
...
script:
- docker login -u $DOCKER_USER -p $ACCESS_TOKEN $CI_REGISTRY
- cd backend
- docker build -f Dockerfile --tag latest .
- docker push latest
...

The first line logs into the GitLab Docker Registry using credentials stored in CI variables. Then it changes to the backend directory, builds the Docker image, and pushes the image to the registry.

Testing is performed in a separate job (e.g., backend_test ) using the same scripts as in the local development environment, with the possibility of adding integration or end‑to‑end tests. After the images are built and stored, they can be pulled into the CI/CD pipeline for further testing.

Finally, deployment jobs pull the newly built images from the GitLab Docker Registry and deploy them to the target servers.

In summary, a monorepo can effectively organize the source code of an application composed of multiple services and libraries. Although deployment becomes more complex, a single tool like GitLab—combining repository management, powerful CI/CD pipelines, and a private Docker registry—can handle the entire workflow.

backendfrontendDockermicroservicesMonorepoGitLab CI/CD
DevOps Cloud Academy
Written by

DevOps Cloud Academy

Exploring industry DevOps practices and technical expertise.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.