GitLab单仓库微服务嵌套流水线部署方案技术问询
Nice approach consolidating your microservices into a monorepo while wanting to keep CI configs modular—nested pipelines in GitLab are exactly the right tool for this job. Let’s walk through how to set this up step by step.
1. Structure Your Monorepo for Modular CI
First, organize your repo so each microservice lives in its own subdirectory, with its own CI configuration file (we’ll avoid naming it .gitlab-ci.yml to prevent conflicts with the root file). Here’s a recommended structure:
your-monorepo/ ├── service-auth/ │ ├── src/ │ ├── Dockerfile │ └── ci-pipeline.yml # Service-specific CI config ├── service-payment/ │ ├── src/ │ ├── Dockerfile │ └── ci-pipeline.yml └── .gitlab-ci.yml # Root pipeline to trigger all sub-pipelines
2. Configure the Root Pipeline to Trigger Nested Pipelines
The root .gitlab-ci.yml will act as a coordinator: it defines a stage to trigger each service’s individual pipeline using GitLab’s trigger keyword. This keeps the root config lean while giving you full control over when services are deployed.
Here’s an example root config that triggers all services on every code commit:
stages: - trigger-all-services # Trigger pipeline for Service Auth trigger-auth-service: stage: trigger-all-services trigger: include: - local: '/service-auth/ci-pipeline.yml' strategy: depend # Optional: Wait for this sub-pipeline to finish before marking root as done # Trigger pipeline for Service Payment trigger-payment-service: stage: trigger-all-services trigger: include: - local: '/service-payment/ci-pipeline.yml' strategy: depend
3. Keep Service-Specific CI Configs Independent
Each service’s ci-pipeline.yml should contain its full build and deployment workflow—just like the .gitlab-ci.yml files you used in separate repos. This way, you maintain full control over each service’s pipeline without cluttering the root config.
Example for service-auth/ci-pipeline.yml:
stages: - build - test - deploy build-auth: stage: build script: - echo "Building auth service..." - docker build -t my-registry/auth-service:$CI_COMMIT_SHA . - docker push my-registry/auth-service:$CI_COMMIT_SHA test-auth: stage: test script: - echo "Running unit tests for auth service..." - npm test deploy-auth: stage: deploy script: - echo "Deploying auth service to its dedicated server..." - ssh user@auth-server "docker pull my-registry/auth-service:$CI_COMMIT_SHA && docker restart auth-service" only: - main # Restrict deployment to your main branch
4. Optional: Optimize to Trigger Only Changed Services
If you later want to avoid triggering pipelines for services with no code changes, add rules: changes to each trigger job in the root config. This will only run the sub-pipeline if files in the service’s directory were modified:
trigger-auth-service: stage: trigger-all-services trigger: include: - local: '/service-auth/ci-pipeline.yml' rules: - changes: - service-auth/**/* # Only trigger if files in this path changed
Key Notes
- GitLab Version Requirement: Nested pipelines with local includes require GitLab 11.7 or newer.
- Strategy Option: Using
strategy: dependensures the root pipeline waits for all sub-pipelines to complete before marking itself as successful—great if you want to enforce that all deployments finish before considering the run done. - Reusability: For shared steps (like common deployment scripts), create a
templates/directory in the root with reusable CI components, then include them in each service’s config usinginclude: local: '/templates/deploy-template.yml'.
This setup gives you the best of both worlds: a single repo for easy maintenance, and modular, independent CI pipelines for each microservice that you can trigger all at once with a single code commit.
内容的提问来源于stack exchange,提问作者Naguib Ihab

