简体   繁体   中英

Docker container rebuild inside of a project

I have a project with the following structure:

  • docker/Dockerfile

  • linux/*.xz (kernel sources)

  • *.sh

  • Jenkinsfile

Basically this pipeline is building a linux kernel inside of a docker container.

We are using bitbucket in combination with jenkins and artifactory for CI/CD.

Currently the building of the docker image is manual: a developr builds it locally and pushes it to artifactory.

The pipeline is only pulling prebuilt docker images for execution.

As this manual interaction is annoying this should be automated.

Typical scenario could look like this: a developer changes the Dockerfile and some other ressource.

This requires us to first rebuild the container, push it to artifactory and afterwards start the build.

Is there a straightforward way to do this using the mentioned technologies?

My approach would be (which is mainly a own implementation) to tag docker images based on their git revision.

When the above mentioned pipeline starts it queries the git-rev of the Dockerfile of the last change and tries to pull the

container. If this is possible - fine. Otherwise run a 'docker build' and push the new container. Afterwards run the kernel build inside.

Is this a proper way to do that?

Possible options are below.

Option 1

In order to determine whether you have to build a new image, you can rely on Jenkins Changeset . You can check whether the docker/Dockerfile file has changed from the last build, if so you can execute the build step or just skip it.

Also, when tagging the image you can create two image tags. One with the revision(Or any other unique identifier) and also replace the latest tag with the latest image built. This will allow you to have a simple logic in consecutive steps of the pipeline since we know that the latest build image is in the latest tag. Sample pipeline below.

pipeline {
    agent any

    stages {
        stage('BuildImage') {
            when { changeset "**/Dockerfile" }
            steps {
                script {
                 def image = docker.build("my-image:REVISION", "docker/Dockerfile")
                 image.push() // Pushes the tagged image with revision
                 image.push('latest') // Change the tag and push
                }
            }
        }
        
        stage('Other Build') {
            steps {
                 docker.image('my-image:latest').inside {
                    // Do other stuff within the Docker image
                }
            }
        }
        
        stage('Other Build option 2') {
            agent {
                docker { image 'node:16.13.1-alpine' }
            }
            steps {
                // Do other stuff within the Docker image
            }
        }
    }
}

Option 2

Another option would be to always start a new Jenkins Agent/Container with your Docker file or always build the image and then execute your build commands with the container. This may be efficient if you do frequent changes to the Dockerfile. Sample pipeline below.

pipeline {
    agent { dockerfile { dir 'docker' } }

        stage('Other Build') {
            steps {
                // Do other stuff within the Docker image
            }
        }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM