如何防止容器从 docker 到 stop/remove 出错

How to prevent from docker to stop/remove the container on error

考虑一下我有一个 Jenkins groovy 代码,运行s docker 容器和一些 bash 将 运行 在里面:

    docker.withRegistry(dockerRegistry, dockerCredentials) {
    docker.image(new String(dockerImage + ":" + dockerVersion)).inside(mountCommand) {

        try {
            withEnv(["AWS_PROFILE=${mappings['stackEnv']}",
                     "FULL_PACKAGE_VERSION=${mappings['revision']}",
                     "ARTIFACTORY_USER=${IC_ARTIFACTORY_USER}"]) {
                withCredentials([
                        string(credentialsId: IC_ARTIFACTORY_KEY, variable: 'ARTIFACTORY_KEY')
                ]) {
                    sh '''
                    bash -x Jenkinsfile-e2e-test.sh
                '''
                }
            }
        } finally { }
    }
}

如果 Jenkinsfile-e2e-test.sh 由于某种原因掉落,Jenkins 将自动停止并移除容器:

09:40:08 $ docker stop --time=1 6e78cf6d940cb1ca1cb1c729617fd3e6ba3fa4085c2750908dff8f2a1e7ffeed
09:40:09 $ docker rm -f 6e78cf6d940cb1ca1cb1c729617fd3e6ba3fa4085c2750908dff8f2a1e7ffeed

如何防止 Jenkins 在失败时销毁容器?

您可以确保命令不会失败:

bash -x Jenkinsfile-e2e-test.sh || true

甚至更好:

bash -x Jenkinsfile-e2e-test.sh > e2e.log 2>&1 & || true
# check the log file and do something based on the log

一旦您的 .inside 命令主体完成,Jenkins 将始终停止并删除容器。无论您的 bash 脚本是成功还是失败。

背后的原因是 jenkins 会为您打扫卫生,以防止您最终在构建机器上挂起大量已停止的容器。

Image.withRunImage.inside 方法就是这种情况。 如果你想控制容器的生命周期,你应该使用 Image.run:

Uses docker run to run the image, and returns a Container which you could stop later

(来自 docs