I want to run Jenkins builds on Windows nodes in Docker containers.

1 Answers

0
Gyorgy Nadaban On

For those looking for ready-to-use answers instead of references to useless documentation pages, here's a Jenkinsfile snippet of how to run Docker builds on Windows 2016/2019:

// invokeDocker.groovy
def call(image, cmd) {
    powershell """
        docker run `
          --rm `
          -w "${env.WORKSPACE}" `
          -v "${env.WORKSPACE}:${env.WORKSPACE}:rw" `
          -e "WORKSPACE=${env.WORKSPACE}" `
          -e "BUILD_NUMBER=${env.BUILD_NUMBER}" `
          $image powershell -C "$cmd"
    """
}

You should use a shared library, eg. using a multi-staged pipeline:

// runDockerStages.groovy
def call(Map pipelineParams) {

    if(!pipelineParams){
        pipelineParams = [:]
    }

    pipeline {
        agent { label "DOCKER-BUILDER" && "SERVER2019" }

        environment {
            SCRIPTS="__scripts"
        }

        options {
            timeout(time: pipelineParams.timeoutMinutes ? pipelineParams.timeoutMinutes : 180, unit: 'MINUTES')
        }

        stages {
            stage('Deploy scripts'){
                steps {
                    initializeWorkspace();
                }
            }

            stage('Trigger custom build stages'){
                steps {
                    executeDockerBuildStages(pipelineParams.Stages);
                }
            }

            stage('Publish'){
                steps{
                    script{
                        publishAllArtifacts();
                    }
                }
            }
        }
        post{
            success{
                // Set latest build URL on Jira case
                updateJira();
            }
        }
    }
}

void executeDockerBuildStages(stageInfos) {
    stageInfos.each { dockerStage ->
        echo("---- About to run [${dockerStage.Title}] stage ----")
        script {
            stage(dockerStage['Title']) {
                invokeDocker(dockerStage['DockerImage'], dockerStage['Script'])
            }
        }
    }
}

Your Jenkinsfile will then look like this:

runDockerStages(
  [ 
    Stages: [
      [ Title: 'Prepare', DockerImage: "imagine/jenkins-pipeline/buildbase-windows:1.0.0-windowsservercore-1809", Script: ". .\\build\\build.Prepare.ps1" ],
      [ Title: 'Test', DockerImage: "imagine/jenkins-pipeline/dotnetcore:2.2.203-windowsservercore-1809", Script: ". .\\build\\build.Test.ps1" ],
      [ Title: 'UI', DockerImage: "imagine/jenkins-pipeline/nodejs:10.15.0-windowsservercore-1809", Script: ". .\\build\\build.ui.ps1" ],
      [ Title: 'Service', DockerImage: "imagine/jenkins-pipeline/dotnetcore:2.2.203-windowsservercore-1809", Script: ". .\\build\\build.service.ps1" ]
  ]
)