Sobes.tech
Middle

How do you version images and integrate this with Jenkins?

sobes.tech AI

Answer from AI

There are various image versioning strategies:

  1. Semantic Versioning: Using MAJOR.MINOR.PATCH.

    • MAJOR: Significant changes (breaking backward compatibility).
    • MINOR: New features (backward compatible).
    • PATCH: Bug fixes (backward compatible).
  2. Git hash versioning: Using the full or shortened hash of the last commit. Ensures uniqueness.

  3. Jenkins build number versioning: Using Jenkins' auto-incremented build number. Simple, but not directly tied to source code.

  4. Combined versioning: A combination, for example, app_version-jenkins_build or app_version-git_commit.

Integration with Jenkins involves the following steps:

  1. Getting the version: In the Jenkins pipeline, define the image version. This can be:

    • Reading the version from a project file (package.json, pom.xml, etc.).
    • Getting the Git commit hash (git rev-parse HEAD).
    • Using the Jenkins environment variable ($BUILD_NUMBER).
  2. Building the image with a tag: Use the docker build command with the -t option to assign a tag.

    # Dockerfile
    FROM ubuntu:latest
    COPY . /app
    # ...
    

    In Jenkinsfile:

    // Jenkinsfile
    pipeline {
        agent any
        stages {
            stage('Build Docker Image') {
                steps {
                    script {
                        def appVersion = sh(returnStdout: true, script: 'cat VERSION').trim() // Example reading from a file
                        def gitHash = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim() // Example getting Git hash
                        def imageTag = "${appVersion}-${gitHash}-${env.BUILD_NUMBER}" // Combined tag
    
                        sh "docker build -t my-app:${imageTag} ."
                    }
                }
            }
        }
    }
    
  3. Tagging for repository (optional): For convenience, create additional tags, such as latest or environment tags (dev, staging, prod).

    // In the same or a new stage
    steps {
        script {
            def imageTag = "${sh(returnStdout: true, script: 'cat VERSION').trim()}-${sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()}-${env.BUILD_NUMBER}"
            sh "docker build -t my-app:${imageTag} ."
            sh "docker tag my-app:${imageTag} my-registry/my-app:latest" // Adding latest tag
        }
    }
    
  4. Push the image to the repository: Use the docker push command with the tag.

    // In a new stage Push Docker Image
    stage('Push Docker Image') {
        steps {
            script {
                def imageTag = "${sh(returnStdout: true, script: 'cat VERSION').trim()}-${sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()}-${env.BUILD_NUMBER}"
                sh "docker push my-registry/my-app:${imageTag}"
                sh "docker push my-registry/my-app:latest" // Push latest tag
            }
        }
    }
    
  5. Applying in deployment: In manifest files (Kubernetes, Docker Compose), use Jenkins environment variables or other mechanisms to specify the desired image version.

    # Kubernetes deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-app
    spec:
      replicas: 3
      template:
        spec:
          containers:
          - name: my-app
            image: my-registry/my-app:${IMAGE_TAG} # Using environment variable
            ports:
            - containerPort: 8080
    

    In Jenkinsfile, during deployment:

    // In the Deployment stage
    stage('Deploy to Kubernetes') {
        environment {
            IMAGE_TAG = "${sh(returnStdout: true, script: 'cat VERSION').trim()}-${sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()}-${env.BUILD_NUMBER}"
        }
        steps {
            sh "kubectl apply -f deployment.yaml --namespace my-namespace"
        }
    }
    

The choice of a specific versioning strategy depends on project and team requirements. A combined approach often provides good traceability from the image to the source code and build number.