You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Jenkins Pipeline在第二台AWS Ubuntu服务器拉取部署Docker镜像

问题根源

你遇到的核心问题是SSH命令的写法错误!当前脚本里的这条命令:

ssh -o StrictHostKeyChecking=no ubuntu@2ndserver && cd /home/ubuntu/ && sudo touch test-file && docker pull docker-user/docker-repo:flask-app-push-test

这里的&&是本地Shell的逻辑运算符,它的执行逻辑是:先通过ssh登录到2nd-server,一旦SSH会话自动退出(因为你没指定要执行的远程命令),就会回到**1st-server(Jenkins代理所在服务器)**执行后面的cd、touch和docker pull——这就是为什么测试文件会出现在1st-server上,完全没在目标服务器上执行操作!

修正方案

1. 正确编写SSH远程执行命令

要让命令在2nd-server上运行,必须把所有需要远程执行的命令作为ssh的参数,用单引号包裹(避免本地Shell解析变量)。修改后的命令应该是:

ssh -o StrictHostKeyChecking=no ubuntu@2ndserver 'cd /home/ubuntu/ && sudo touch test-file && docker pull docker-user/docker-repo:flask-app-push-test'

单引号里的所有命令都会在2nd-server的SSH会话中执行,完成后自动退出会话。

2. 解决远程sudo的密码阻塞问题

远程执行sudo时默认会要求输入密码,这会导致Jenkins Pipeline卡住。你需要在2nd-server上给ubuntu用户配置免密sudo权限:

  • 登录2nd-server,执行sudo visudo(安全编辑sudoers文件)
  • 根据安全需求二选一添加配置:
    • 完全免密(简单但权限范围大):
      ubuntu ALL=(ALL) NOPASSWD: ALL
      
    • 仅允许特定命令(更安全):
      ubuntu ALL=(ALL) NOPASSWD: /usr/bin/touch, /usr/bin/docker
      

3. 优化Pipeline结构(可选但推荐)

把部署步骤从镜像推送阶段分离出来,单独做一个Deploy to 2nd-server阶段,让Pipeline逻辑更清晰。另外,Build阶段的docker run如果重复执行会报错(容器已存在),可以加前置判断清理旧容器。

修正后的完整Pipeline脚本

pipeline {
    environment {
        registry = "docker-user/docker-repo"
        registryCredential = 'docker-cred'
        dockerImage = ''
    }
    agent any
    stages {
        stage('Cloning Git') {
            steps {
                git url: 'https://github.com/git-user/jenkins-flask-tutorial.git/'
            }
        }
        stage('Building image') {
            steps{
                script {
                    // 先清理旧容器(如果存在),避免重复运行报错
                    sh "sudo docker stop flask-app-one || true"
                    sh "sudo docker rm flask-app-one || true"
                    // 构建并运行容器
                    sh "sudo docker build -t flask-app-one ."
                    sh "sudo docker run -p 5000:5000 --name flask-app-one -d flask-app-one "
                    // 打标签准备推送
                    sh "docker tag flask-app-one:latest ${registry}:flask-app-push-test"
                }
            }
        }
        stage('Push Image to Docker Hub') {
            steps{
                script {
                    docker.withRegistry( '', registryCredential ) {
                        sh "docker push ${registry}:flask-app-push-test"
                    }
                }
            }
        }
        stage('Deploy to 2nd-server') {
            steps {
                sshagent(['my-ssh-key']) {
                    sh '''
                        ssh -o StrictHostKeyChecking=no ubuntu@2ndserver '
                            cd /home/ubuntu/ && 
                            sudo touch test-file && 
                            docker pull docker-user/docker-repo:flask-app-push-test
                        '
                    '''
                }
            }
        }
    }
}

额外提示

  • sshagent加载密钥的部分是正确的,只要Jenkins凭证里的my-ssh-key是2nd-server的私钥就没问题。
  • 如果远程执行docker pull时提示权限问题,可在2nd-server执行sudo usermod -aG docker ubuntu,把ubuntu用户加入docker组,之后就不需要用sudo docker命令了。

内容的提问来源于stack exchange,提问作者rajeev singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 09:22:47