Home > Back-end >  My Jenkins pipeline sh command doesn't reference the correct machine
My Jenkins pipeline sh command doesn't reference the correct machine

Time:01-30

So, I have the following pipeline

pipeline {
    agent any 

    environment {
      UPLOADED_FILES_DIR='/tmp/spring_fileupload_dir'
      DOCKER_USR=credentials('docker_usr')
      DOCKER_PASSWD=credentials('docker_passwd')
    }

    stages {
        stage('Test') { 
            steps {
                sh 'mvn test' 
            }
        }

        stage('Package') { 
            steps {
                sh 'mvn clean package -Dmaven.test.skip=true' 
            }
        }

        stage('Build') { 
            steps {
                sh """
                    docker build -t azold6/fileupload-pv-pvc:$BUILD_NUMBER . 
                """ 
            }
        }

        stage('Push') { 
            steps {
                sh """
                    docker login -u="$DOCKER_USR" -p="$DOCKER_PASSWD"
                    docker push azold6/fileupload-pv-pvc:$BUILD_NUMBER
                """ 
            }
        }

        stage('Deploy') { 
            steps {
                sshagent(credentials : ['key-to-ec2']) {
                    sh "docker run -d --name fileupload --rm azold6/fileupload-pv-pvc:$BUILD_NUMBER"
                }
            }
        }
    }
}

When I reach the "Deploy" part, my Jenkins shows the following error:

docker: Error response from daemon: Conflict. The container name "/fileupload" is already in use by container "d7c3ee093de7a06c90e71db1bfc85df849ee218da3ae0cf59aa0bd733d9501e2". You have to remove (or rename) that container to be able to reuse that name.

The problem is, the container "fileupload" is running in the Jenkins container, and not at the targeted EC2 instance. Jenkins is referencing the wrong machine, even though I'm using the SSH agent plugin.

Any idea on how to fix this?

CodePudding user response:

I think you are confusing the functionality of two different plugins.

The SSH Agent Plugin allows you to provide SSH credentials to builds via a ssh-agent in Jenkins, and is actually a shortened form of using the generic withCredentials step to bind an SSH private key to a temporary file, and then pass that to commands that require it (for example using the -i option to ssh or scp).
So this step executes the shell command on your local agent (node) like any other plugin.

What you actually want is to run your shell commands on a remote machine, to which you will connect using the provided ssh credentials.
To achieve that you need to use the SSH Pipeline Steps (Official Site) which are Jenkins pipeline steps that provide SSH facilities such as command execution or file transfer to a remote host.
Usage example:

stage('Deploy') { 
    steps {
         script {
             withCredentials([sshUserPrivateKey(credentialsId: "key-to-ec2", keyFileVariable: 'sshKey', usernameVariable: 'sshUser')]) {
                 // Define the remote host configuration
                 def remote = [:];
                 remote.name = 'ec2-docker-host';
                 remote.host = '127.0.0.1';
                 remote.user = sshUser; 
                 remote.identifyFile = sshKey;
                 remote.allowAnyHosts = true;

                 // Once the remote host is defined, execute remote commands using the sshCommand step
                 sshCommand remote: remote, command: "ls -lrt"
                 sshCommand remote: remote, command: "for i in {1..5}; do echo -n \"Loop \$i \"; date ; sleep 1; done"
            } 
        }
    }
}
  • Related