I am starting to use Continuous Integration on my microservices solution (monorepo approach), and I am referencing this post for versioning approach.

But, let's say I make some change in one of the microservice and commit that change, but all the others are exactly the same. How the process would know that those microservices (docker images) weren't changed so don't need to increase the build number? I feel like I would end-up with many docker images with different build numbers but same content.

Am I misunderstanding the concept? Sorry, this whole microservices and docker thing are pretty new to me.

  • Hi @renatogpb, welcome to SO. The whole idea behind micro-services is that you could make changes in one of them and deploy just that, without affecting other parts of your infrastructure. Could you please go into more detail about how your CI works ? Which process are you referring to ? – vishnu narayanan Sep 16 at 6:51
  • Hi @vishnunarayanan, thanks! So I didn’t implement the actually CI yet, but I was thinking about doing: checkout repository, build de images using “docker-compose -d —build” (I would set some environment variable to replace {$TAG} of the images, and then “docker push”. So, I know what microservices I made the change, but the CI doesn’t know. That’s why I am building all the images. How can I make the CI know about which one I’ve changed? – renatogbp Sep 16 at 12:50

How it should look like:

  1. Commit changes in some microservice and push it to VCS origin repo
  2. CI system sees new commit
  3. CI starts build and tests
  4. If everything's good, it pushes image to docker registry with tags

So, the answer is: CI should know, what service has changes.

  • Hi @chupasaurus, how CI would know? I would have to make different build scripts for different branches? – renatogbp Sep 16 at 13:31
  • @renatogbp CI should have triggers for commits. – chupasaurus Sep 16 at 14:02
  • I know it has triggers, but it will be based on the default job. My solution file includes 4 microservices. If I add a new commit, the job will build the whole solution and publish all 4 images again, even though I had changed only one microservice – renatogbp Sep 16 at 14:12
  • Microservices should be independent to each other so you could separate build/deploy pipelines for each one. – chupasaurus Sep 16 at 14:16
  • Hmm, so that means I should have a VCS origin repo for each microservice? And also one repo for the gateway? – renatogbp Sep 16 at 14:21

@chupasaurus gave an answer based on a multi-repo solution.

Based on this answer, I came up with the following jenkins pipeline approach. I've decided to build and test the whole solution, but you can use the same approach from "Push Image" stage to build and test only the changed services.

pipeline {
agent any
environment {
    CHANGES = getChangeLog()
stages {
    stage('Build') {
        steps {
            bat 'dotnet clean solutionFile.sln'
            bat 'dotnet build solutionFile.sln'
    stage('Test') {
        steps {
            bat 'dotnet test solutionFile.sln --no-build --logger:trx;LogFileName=results.trx'
            // parse tests
    stage('Push Image') {
        stage('serviceA') {
            when {
                allOf {
                        expression {
                            hasChanged = powershell(returnStdout: true, script: '"$env:CHANGES" -like "*serviceA*").trim() // check if any file path contains "serviceA"
                            return  hasChanged == "True" 
                        branch 'master'
            steps {   
                // set tag or use latest by default from docker-compose      
                bat 'docker-compose build serviceA.api'
                bat 'docker-compose push registry/serviceA.api'
    stage('Deploy Image') {
        stage('serviceA') {
            // deploy image code

def getChangeLog(){
    def changes = ""
    build = currentBuild
    while(build != null && build.result != 'SUCCESS') {
        changes += "In ${build.id}:\n"
        for (changeLog in build.changeSets) {
            for(entry in changeLog.items) {
                for(file in entry.affectedFiles) {
                    changes += "${file.path}\n"
        build = build.previousBuild
    echo changes
    return changes

This code isn't fully tested, I just wanted to give a practical approach.

Your Answer


By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.