A strange reluctance to be critical

How to build a staging server with Docker, Jenkins and Traefik

~ Chapter 3 ~

Writing invokable Jenkins jobs

Jenkins jobs will be automatically configured at runtime during the pipeline stage through the Jenkinsfile found in the project’s root. While we could write all the code required by an application directly in the file, it is more elegant to extract reusable processes in additional Jenkins tasks. This give the luxury of performing updates on the job without having to go through each projects.

Additionally, also because of the Docker-in-Docker problem discussed previously, you cannot call the host server’s Docker instance while you are in a build container.

For example, say you are running a build of an Node app that needs to be build using node:latest, you will not be able to invoke Docker from within the Node container:

Jenkins does not like Docker in Docker Jenkins does not like Docker in Docker

The only way I have found to go around that problem is for the build job to delegate the Docker operation to another Jenkins job specialized in handling the task which will not run in a child container. As it doesn’t use a Docker agent and remains in the Jenkins container, that job will be allowed access.

Staying one level deep works well Staying one level deep works well

pipeline {
	options {
        disableConcurrentBuilds()
        buildDiscarder(logRotator(numToKeepStr: '5'))
    }
    post { always { deleteDir() } }
    agent any
    stages {
        // The pipeline thinks we are updating the current repository:
        stage('Deploy') {
            when { expression { params.DEPLOY_JOB_NAME == null } }
            steps {
                sh "mkdir -p /dev-ops/docker-staging-swarm/"
                sh "rm -rf /mutation/dev-ops/staging-swarm/*"
                sh "cp ${WORKSPACE}/* /mutation/dev-ops/staging-swarm/"
                sh "rm /mutation/dev-ops/staging-swarm/Jenkinsfile"
                sh "chmod +x /mutation/dev-ops/staging-swarm/*"
            }
        }
        // The pipeline thinks a job has required an update from us
        stage('Deploy') {
            when { expression { params.DEPLOY_JOB_NAME != null } }
            steps {
                sh "/mutation/dev-ops/staging-swarm/stage-docker-image ${params.SOURCE_DIRECTORY} ${params.DEPLOY_JOB_NAME}"
            }
        }
    }
}

Read other articles