How do you version images and integrate this with Jenkins?
sobes.tech AI
Answer from AI
There are various image versioning strategies:
-
Semantic Versioning: Using MAJOR.MINOR.PATCH.
- MAJOR: Significant changes (breaking backward compatibility).
- MINOR: New features (backward compatible).
- PATCH: Bug fixes (backward compatible).
-
Git hash versioning: Using the full or shortened hash of the last commit. Ensures uniqueness.
-
Jenkins build number versioning: Using Jenkins' auto-incremented build number. Simple, but not directly tied to source code.
-
Combined versioning: A combination, for example,
app_version-jenkins_buildorapp_version-git_commit.
Integration with Jenkins involves the following steps:
-
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).
- Reading the version from a project file (
-
Building the image with a tag: Use the
docker buildcommand with the-toption 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} ." } } } } } -
Tagging for repository (optional): For convenience, create additional tags, such as
latestor 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 } } -
Push the image to the repository: Use the
docker pushcommand 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 } } } -
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: 8080In 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.