Как создать новый контейнер docker и запустить его из Jenkinsfile

#docker #jenkins #jenkins-pipeline

#докер #дженкинс #дженкинс-конвейер

Вопрос:

Я унаследовал этот Jenkinsfile этап, который будет запускать новый образ docker с помощью withRun :

 stage('Deploy') {
    steps {
        script {
            docker.image('deployscript:latest').withRun("""
                -e 'IMAGE=${IMAGE_NAME}:${BUILD_ID}' 
                -e 'CNAME=${IMAGE_NAME}' 
                -e 'PORT=${PORT_1}:80' 
                -e 'PORT=${PORT_2}:443'""") { c ->
                    sh "docker logs ${c.id}"
                }
        }
    }
}
 

Однако я считаю, что этот метод предназначен только для целей тестирования и фактически останавливает контейнер после завершения блока. Я хочу, чтобы этот шаг фактически запустил контейнер и остановил / перезапустил предыдущий, если это необходимо. Документация по этому вопросу на удивление скудная. Пожалуйста, помогите.

Комментарии:

1. Попробуйте использовать bash для этого вместо groovy.

Ответ №1:

Если вы хотите запустить контейнер docker на всех этапах, то пример будет выглядеть следующим образом:

Скриптовый конвейер

 node('master') {
    /* Requires the Docker Pipeline plugin to be installed */
    docker.image('alpine:latest').inside {
       stage('01') {
         sh 'echo STAGE01'
       }
       stage('02') {
         sh 'echo STAGE02'
       }
    }
}
 

Декларативный конвейер

 pipeline {
    agent {
        docker {
            image 'alpine:latest'
            label 'master'
            args  '-v /tmp:/tmp'
        }
    }
    stages {
        stage('01') {
            steps {
                sh "echo STAGE01"
            }
        }
        stage('02') {
            steps {
                sh "echo STAGE02"
            }
        }
    }
}
 

Как в скриптовых, так и в декларативных конвейерах контейнер docker из alpine image будет активен для завершения всех этапов и будет удаляться только в случае успешного или неудачного завершения этапа.

Но если вы хотите самостоятельно управлять запуском, остановкой и перезапуском контейнера на разных этапах, вы можете сделать это с помощью команды bash или написав небольшой скрипт groovy, обертывающий команду docker, как показано ниже

 node {
  stage('init') {
    docker create --name myImage1 -v $(pwd):/var/jenkins -w /var/jenkins imageName:tag
  }
  stage('build') {
    // make use of docker command to start, stop and execute some script inside the container
    // same goes for other stage
    //once all done you can remove the container
    docker rm myImage1 
  }
}

 

Комментарии:

1. Я просто хочу, чтобы мой конвейер заменил уже существующий контейнер на хосте контейнером с новым изображением. Я не спрашиваю о запуске контейнера в конвейере. Имеет ли это различие смысл? Я довольно новичок в Docker.

Ответ №2:

Следующее остановит существующий контейнер и запустит новый с новым изображением:

 stage('Deploy') {
    steps {
        sh "docker stop ${IMAGE_NAME} || true amp;amp; docker rm ${IMAGE_NAME} || true"
        sh "docker run -d 
            --name ${IMAGE_NAME} 
            --publish ${PORT}:443 
            ${IMAGE_NAME}:${BUILD_ID}"
    }
}