Run docker build inside Jenkins Docker Slave

Viewed 367

Currently I've a CI pipeline with the following stages:

  1. Build
  2. Unit Tests
  3. Static Code Analysis

This is how my Jenkinsfile looks like:

pipeline {
  agent any

  stages {
    stage("Install") {
      steps {
        sh "npm install"
      }
    }
    stage("Build") {
      steps {
        sh "npm run build"
      }
    }
    stage("Format") {
        steps {
            sh "npm run format"
        }
    }
    stage("Lint") {
      steps {
        sh "npm run lint"
      }
    }
    stage("Test") {
      steps {
        sh "npm run test"
      }
    }
    stage("Code Coverage") {
      steps {
        sh "npm run test:cov"
        publishHTML(target: [
            reportDir: "./coverage/lcov-report",
            reportFiles: "index.html",
            reportName: "Jest Coverage Report"
        ])
      }
    }
    stage("End-To-End Testing") {
      steps {
        sh "npm run test:e2e"
      }
    }
  }
}

I want to add more stages to my pipeline:

  1. Build and tag Docker Image from Dockerfile
  2. Push the image to the Docker Hub
  3. Some more steps which would need Docker CLI

Example:

pipeline {
  .
  .
  .
  stage("Docker Build") {
    steps {
      sh "docker build -t [user_name]/[image_name]:[tag] .
    }
  }
}

I'm quite new to this, and I have tried multiple ways to install docker and it was unsuccessful and it is a bad practice too.

We can run docker run -v /var/run/docker.sock:/var/run/docker.sock ... but I can't use bind mounting while using docker build command.

Can someone please suggest me a way where I can use docker commands inside Jenkins SSH Agents?

1 Answers

Solution

  1. Install Docker CLI without the Daemon in Jenkins Docker Slave. I have used this Docker Agent and installed Docker CLI inside it using this method
  2. Then as a docker daemon I've used my remote docker host. (Also, you can configure the local docker host as remote using these steps). You can use docker remote host using --host flag. E.g. docker --host x.x.x.x:2375 build -t johndoe:calculator .
  3. Syntax: docker --host [Docker_Host]:[Port] build -t [Image_Name]:[Image_Tag] .

My New Jenkinsfile is as follows:

pipeline {
  agent any

  stages {
    stage("Install") {
      steps {
        sh "npm install"
      }
    }
    stage("Build") {
      steps {
        sh "npm run build"
      }
    }
    stage("Format") {
        steps {
            sh "npm run format"
        }
    }
    stage("Lint") {
      steps {
        sh "npm run lint"
      }
    }
    stage("Test") {
      steps {
        sh "npm run test"
      }
    }
    stage("Code Coverage") {
      steps {
        sh "npm run test:cov"
        publishHTML(target: [
            reportDir: "./coverage/lcov-report",
            reportFiles: "index.html",
            reportName: "Jest Coverage Report"
        ])
      }
    }
    stage("End-To-End Testing") {
      steps {
        sh "npm run test:e2e"
      }
    }
    stage("Docker Build") {
      steps {
        withCredentials([string(credentialsId: 'Docker_Host', variable: 'DOCKER_HOST')]) {
          sh 'docker --host $DOCKER_HOST build -t xxx/xxx .'
        }
      }
    }
  }
}

Note: I have stored Docker host URL on Jenkins as a credential and used it using withCredentials function.

Related