Jenkins流水线Docker部署回滚及容器移除异常求助
Jenkins持续部署流水线问题修复方案
问题1:回滚时提示找不到镜像
问题原因
- 部署仅推送带
${env.BUILD_NUMBER}标签的镜像,未同步推送latest标签作为稳定版本标记,本地也不存在无标签镜像(Docker默认拉取latest标签,原命令未指定标签导致匹配失败)。 - 回滚命令未指定具体稳定版本,直接使用无标签镜像触发查找失败。
修复方案
- 在镜像推送环节新增
latest标签推送,标记当前成功构建为稳定版本 - 回滚时明确指定
latest标签拉取稳定镜像
修改后的deployContainer函数
def deployContainer(imageName) { docker.withRegistry('https://registry.hub.docker.com', 'dockerhub_credentials') { def customImage = docker.build("${env.DOCKER_REPO}/${imageName}:${env.BUILD_NUMBER}") // 推送带构建号的镜像 customImage.push() // 推送latest标签镜像,标记为当前稳定版本 customImage.push('latest') } }
修改后的回滚命令
将post阶段的回滚命令更新为:
runCmd("docker run -d -p 3002:3000 --restart unless-stopped --name ${env.DOCKER_CONTAINER_NAME} ${env.DOCKER_REPO}/${env.DOCKER_IMAGE_NAME}:latest")
问题2:容器移除失败导致新容器无法启动
问题原因
removeContainer函数中,runCmd使用returnStatus: true时返回的是命令退出状态码(0=成功,非0=失败),而非docker ps -q的输出内容,原判断逻辑将状态码当作容器存在标识,逻辑错误。docker ps -q -f name=${containerName}仅检查运行中的容器,忽略已停止容器,导致停止状态的容器未被清理。
修复方案
- 调整容器存在性判断逻辑:通过状态码0判断容器存在
- 使用
docker ps -a检查所有状态的容器(含已停止) - 添加
-f参数强制删除容器,确保清理彻底
修改后的removeContainer函数
def removeContainer(containerName) { // 检查所有状态的容器是否存在(包括已停止) def containerExists = runCmd("docker ps -a -q -f name=${containerName}") // 状态码为0表示容器存在 if(containerExists == 0) { // 停止容器(如果运行中) runCmd("docker stop ${containerName}") // 强制移除容器 runCmd("docker rm -f ${containerName}") } }
完整优化后的流水线阶段代码
stage('Continuous deployment') { stages { stage('Build and Push Docker Image') { steps { echo 'Build and Pushing image...' script { deployContainer(env.DOCKER_IMAGE_NAME) } echo 'Image pushed' } } stage('Run Docker Image') { steps { echo 'Running image...' script { removeContainer(env.DOCKER_CONTAINER_NAME) // 启动带构建号的新镜像 runCmd("docker run -d -p 3002:3000 --restart unless-stopped --name ${env.DOCKER_CONTAINER_NAME} ${env.DOCKER_REPO}/${env.DOCKER_IMAGE_NAME}:${env.BUILD_NUMBER}") } echo 'Running' } post { failure { echo 'Rolling back to latest stable image...' // 回滚前先清理残留容器 removeContainer(env.DOCKER_CONTAINER_NAME) runCmd("docker run -d -p 3002:3000 --restart unless-stopped --name ${env.DOCKER_CONTAINER_NAME} ${env.DOCKER_REPO}/${env.DOCKER_IMAGE_NAME}:latest") } } } } }
内容的提问来源于stack exchange,提问作者Atram
相关产品推荐
相关产品推荐

