Skip to content

esign-consulting/myjenkins

Repository files navigation

Jenkins custom Docker image

License: MIT Docker Build status Docker Pulls

This custom Jenkins image is built with the following features:

Preinstalled plugins

A bunch of plugins are installed during the image build. Once they increase the image size considerably, the Alpine version of the Jenkins Docker image is used as the base image (jenkins/jenkins:lts-alpine), in order to keep the built image as small as possible.

Most of the plugins enable other features, as described below.

Default administrator

The default Jenkins administrator account is created during the execution of default-user.groovy. Its credentials are obtained from the environment variables:

  • JENKINS_USER (default: admin)
  • JENKINS_PASS (default: jenkins)

No setup wizard

With preinstalled plugins and a default administrator, there is no need of following the Jenkins wizard during its setup. For this reason, the wizard is disabled: -Djenkins.install.runSetupWizard=false.

Default location configuration

The default Jenkins location is configured during the execution of config-location.groovy. The Jenkins URL and the e-mail address Jenkins use as the sender for e-mail notification are obtained from the environment variables:

Default Maven installation

The default Apache Maven installation is configured during the execution of config-maven.groovy. The Maven version is obtained from the environment variable:

  • MAVEN_VERSION (default: 3.6.3)

Maven can then be referenced by M3 in the Jenkinsfile, like in the example below:

node {
    def mvnHome = tool 'M3'
    ...
    stage('Build and Unit Tests') {
        sh "'${mvnHome}/bin/mvn' clean install"
    }
    ...
}

Capability of running Ansible playbooks

The default Ansible installation is configured during the execution of config-ansible.groovy. Ansible can then be referenced by Ansible in the Jenkinsfile, like in the example below:

node {
    ...
    stage('Deploy to AWS') {
        withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: 'aws', accessKeyVariable: 'AWS_ACCESS_KEY_ID', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]) {
            ansiblePlaybook(installation: 'Ansible', playbook: 'deploy-to-aws.yml')
        }
    }
    ...
}

This feature is enabled by the Ansible plugin.

Docker in Docker

The myjenkins Docker image is prepared itself to enable the execution of Docker commands. So, you are able to run pipelines in the myjenkins Docker container that build Docker images, push Docker images to a Docker Registry or execute any other Docker command (example below). The only requirement is to bind mount your host Docker daemon Unix socket to the container Docker daemon Unix socket: -v /var/run/docker.sock:/var/run/docker.sock.

node {
    def appDockerImage
    ...
    stage('Build Docker Image') {
        appDockerImage = docker.build("esignbr/logistics")
    }
    stage('Deploy Docker Image') {
        docker.withRegistry("", "dockerhub") {
            appDockerImage.push()
        }
    }
    ...
}

Adding a global credentials

A new global credentials can be created in Jenkins with the execution of add-credentials.groovy. It only happens if the following environment variables are defined:

  • CREDENTIALS_ID
  • CREDENTIALS_USER
  • CREDENTIALS_PASS

The global credentials can then be referenced by its credentialsId in the Jenkinsfile, like in the example below:

node {
    ...
    stage('Deploy Java Artifacts') {
        withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'ossrh', usernameVariable: 'OSSRH_USER', passwordVariable: 'OSSRH_PASSWORD']]) {
            sh "'${mvnHome}/bin/mvn' -s .travis.settings.xml source:jar deploy -DskipTests=true"
        }
    }
    ...
}

Adding an AWS credentials

A new AWS credentials can be created in Jenkins with the execution of add-aws-credentials.groovy. It only happens if the following environment variables are defined:

  • AWS_CREDENTIALS_ID
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

The AWS credentials can then be referenced by its credentialsId in the Jenkinsfile, like in the example below:

node {
    ...
    stage('Deploy to AWS') {
        withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: 'aws', accessKeyVariable: 'AWS_ACCESS_KEY_ID', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]) {
            ansiblePlaybook(installation: 'Ansible', playbook: 'deploy-to-aws.yml')
        }
    }
    ...
}

This feature is enabled by the CloudBees AWS Credentials plugin.

In-process Script Approval

An in-process script or a method signature can be approved in Jenkins with the execution of approve-signature.groovy. It only happens if the following environment variable is defined:

  • SIGNATURE

Integration with Bitbucket

Jenkins can be integrated to Bitbucket with the execution of config-bitbucket.groovy. It only happens if the following environment variables are defined:

  • BITBUCKET_URL - the endpoint where your Bitbucket instance is available
  • BITBUCKET_CREDENTIALS_ID - the global credentials id previously added to Jenkins with the Bitbucket username and password

This feature is enabled by the Bitbucket Branch Source plugin.

Integration with SonarQube

Jenkins can be integrated to SonarQube with the execution of config-sonarqube.groovy. It only happens if the following environment variable is defined:

  • SONARQUBE_URL - the endpoint where your SonarQube instance is available

⚠️ If you have disabled anonymous access in SonarQube and have generated an user token for performing the static code analysis, set the environment variable SONARQUBE_TOKEN.

SonarQube can then be referenced by SonarQube in the Jenkinsfile, like in the example below:

node {
    ...
    stage('Static Code Analysis') {
        withSonarQubeEnv('SonarQube') {
            sh "'${mvnHome}/bin/mvn' sonar:sonar"
        }
    }
    ...
}

ℹ️ You don't need to pass the installationName parameter to withSonarQubeEnv if just one SonarQube server was configured in Jenkins. More details in Using a Jenkins pipeline.

This feature is enabled by the SonarQube plugin.

Integration with Slack

Jenkins can be integrated to Slack with the execution of config-slack.groovy. It only happens if the following environment variables are defined:

  • SLACK_WORKSPACE
  • SLACK_TOKEN

Slack can then be used in the Jenkinsfile, like in the example below:

node {
    ...
    stage('Results') {
        ...
        slackSend(channel: 'builds', message: 'Pipeline succeed!', color: 'good')
    }
}

This feature is enabled by the Slack Notification plugin.

JVM Metrics

The Jenkins JVM metrics are exposed by jmx_exporter, a process for exposing JMX Beans via HTTP for Prometheus consumption. The JVM metrics are exposed through port 8081, as passed to the Java Agent:

-javaagent:/usr/bin/jmx_exporter/jmx_prometheus_javaagent.jar=8081:/usr/bin/jmx_exporter/config.yaml

UI tests capability

The Jenkins image has installed Firefox ESR and geckodriver (available in /usr/local/bin/geckodriver), enabling that way UI tests with Selenium.

The example below shows how the UI test can be performed during the execution of your Jenkinsfile:

node {
    ...
    stage('UI Tests') {
        sh "'${mvnHome}/bin/mvn' -f test-selenium test -Dwebdriver.gecko.driver=/usr/local/bin/geckodriver -Dheadless=true"
    }
    ...
}

Jenkins hardening

The Jenkins security is improved during the execution of harden-jenkins.groovy and default-project-authorization.groovy, when the following actions are taken: