I have the following pipeline:
pipeline {
environment {
registry = "my-docker"
registryCredential = 'dockerhubcredentials'
dockerImage = ''
}
agent any
stages {
stage('Cloning our Git') {
steps {
git 'my-git'
}
}
stage('Building Docker Image') {
steps {
script {
dockerImage = docker.build registry ":$BUILD_NUMBER"
}
}
}
stage('Deploying Docker Image to Dockerhub') {
steps {
script {
docker.withRegistry('', registryCredential) {
dockerImage.push()
}
}
}
}
stage('Cleaning Up') {
steps{
sh "docker rmi --force $registry:$BUILD_NUMBER"
}
}
stage('Upgrade docker') {
steps{
// sh docker stop *Current CONTAINERID* (How do I get it?)
// sh docker run my-container:*NEW_BUILD_NUMBER*
}
}
}
}
Now I'm trying to add the upgrade docker stage, all other steps are working great.
How I can get the current container ID of the container I'm looking for in order to stop it?
After stop I want to pull and start the new one (I'll need the new build number, possibly
$BUILD_NUMBER 1
, I think I can manage that - correct me if I'm wrong.Is it a good practice to upgrade a docker container in jenkins? I couldn't find any examples and it feels common automation process.
CodePudding user response:
If we address the two steps you are attempting to achieve in the pipeline and implement them, then your first two literal questions become irrelevant because they do not affect the implementation.
First, for stopping the container:
// sh docker stop *Current CONTAINERID* (How do I get it?)
your pipeline never runs a container, so you have no container to stop, and can safely skip this step method.
Second, for running the new container:
// sh docker run my-container:*NEW_BUILD_NUMBER*
The new container will be sourced from your new image, and your new image is part of the return object from your docker.build
global variable method. Therefore, we can run your new container like:
// three methods available here
dockerImage.run([args, command])
dockerImage.withRun[(args[, command])] {…}
dockerImage.inside[(args)] {…}
because you assigned the return to dockerImage
.
For the third question, building a new Docker image and running a new container as part of a pipeline is absolutely common. You can add various other stages to your pipeline if you want, such as deploying the new image to a Kubernetes cluster.
CodePudding user response:
If you are deploying this through a Jenkins pipeline, you'll usually want to directly specify the name for the container:
sh "docker run -d --name my-container $registry:$BUILD_NUMBER"
Once you have that name, you can clean up the old container using that name, without having to know the container ID
sh 'docker stop my-container'
sh 'docker rm my-container'
The other important corollary to this is that you probably shouldn't docker rmi
the newly-built image before you docker run
it. Docker will pull the image you just pushed, but you just had that exact thing a minute ago. You might want to clean up the old image, maybe by using docker system prune
to clean up anything unused.
Putting it all together, the end of your pipeline would be:
environment {
...
containerName = 'my-container'
}
stages {
...
stage('Upgrade docker') {
steps {
sh script: "docker stop $containerName", returnStatus: true
sh script: "docker rm $containerName", returnStatus: true
sh "docker run -d --name $containerName $registry:$BUILD_NUMBER"
}
}
stage('Cleaning up') {
steps {
sh "docker system prune --all --force"
}
}
}