Cloud Native 6 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 build, test, and deploy the services using Docker, docker‑compose, and GitLab CI/CD pipelines with selective job execution based on code changes.

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

Modern web applications often consist of multiple services such as a backend API and a frontend client, and large projects may further split these into micro‑services; organizing the source code can be done with a monorepo (single repository) or separate repositories for each service.

The monorepo approach simplifies code reuse and dependency management, but it introduces more complex semantic versioning and deployment processes for each service.

An example project is presented that contains only two services—a Node.js backend providing a REST/GraphQL API and a JavaScript‑based frontend (React or Vue) serving a single‑page application—both managed in a single monorepo with the following file structure:

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

Docker containers are used for both local development and production; each service has its own Dockerfile and a docker‑compose.yaml configures and starts the containers locally, while the same images can be orchestrated with tools like Kubernetes in production.

The CI/CD pipeline aims to automatically build, test, and deploy the application whenever new code is pushed to GitLab. The pipeline builds Docker images for changed services, stores them in a private GitLab Docker Registry, and triggers the server to pull the new images.

GitLab CI/CD defines stages such as build , test , and deploy . The .gitlab-ci.yaml file uses the only/changes clause with path‑based regular expressions so that jobs run only for services whose source code has changed.

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

The build job script consists of four commands that log in to the GitLab Docker Registry, change to the backend directory, build the Docker image, and push it to the registry:

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

After building, a separate test job (e.g., backend_test ) runs the same test scripts used locally, and can also execute integration or end‑to‑end tests as needed.

Finally, a deploy job logs into the target server and pulls the newly built image from the GitLab registry, completing the automated deployment process.

In summary, a monorepo can effectively organize the source code of multi‑service applications; although deployment becomes more involved, a single toolchain such as GitLab CI/CD combined with Docker provides a streamlined solution.

DockermicroservicesdevopsMonorepoContainerizationGitLab 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.