sshjenkins-groovy

How to define a variable first right after SSH into a remote server?


I want to redeploy a docker container via Jenkinsfile on a remote EC2, but I struggle to find a solution that works with ssh. I want to have to lookup if the container already exist and remove it first.

What I tried: I wrote a script which works on my local machine but there is no need for ssh.

This is the working stage from my Jenkinsfile.

        stage('Deploy Docker container on HOST') {
            steps {
                script {
                    // Check if container exists
                    def containerId = sh(script: "docker ps --quiet --filter name=$CONTAINER_NAME", returnStdout: true).trim()

                    if (containerId.isEmpty()) {
                        echo "Container $CONTAINER_NAME not found. Skipping stop/remove steps."
                    } else {
                        echo "Stopping and removing existing container $CONTAINER_NAME ..."
                        sh "docker stop $CONTAINER_NAME"
                        sh "docker rm $CONTAINER_NAME"
                        sh "docker rmi $DOCKERH_REPO/$IMAGE_TAG:latest" // Remove leftover image if needed
                        sh "docker rmi $DOCKERH_REPO/$IMAGE_TAG:$BUILD_VERSION" // Remove leftover image if needed
                    }

                    // Always run the container regardless of previous existence
                    echo "Starting container $CONTAINER_NAME ..."
                    sh "$DOCKER_RUN"
                    sh "docker image prune --force"
                }
            }
        }

Now I would like to be able to do the same but on a remote server via SSH. I moved the cript to an external groovy for this stage to be more clean.

Stage

        stage('Deploy Docker container on EC2') {
            steps {
                script {
                    sshagent(['aws-ssh']) {
                        sh "ssh -o StrictHostKeyChecking=no ec2-user@35.157.110.150 'xgs.buildEC2()'"
                    }
                }
            }
        }

jenkins.groovy script

def buildEC2() {
    // Check if container exists
    def containerId = sh(script: "docker ps --quiet --filter name=$CONTAINER_NAME", returnStdout: true).trim()

    if (containerId.isEmpty()) {
        echo "Container $CONTAINER_NAME not found. Skipping stop/remove steps."
    } else {
        echo "Stopping and removing existing container $CONTAINER_NAME ..."
        sh "docker stop $CONTAINER_NAME"
        sh "docker rm $CONTAINER_NAME"
        sh "docker rmi $DOCKERH_REPO/$IMAGE_TAG:latest" // Remove leftover image if needed
        sh "docker rmi $DOCKERH_REPO/$IMAGE_TAG:$BUILD_VERSION" // Remove leftover image if needed
    }

    // Always run the container regardless of previous existence
    echo "Starting container $CONTAINER_NAME ..."
    sh "$DOCKER_RUN"
    sh "docker image prune --force"
}

return this

Just deploying the container works good (executing commands like docker run with params etc).

What I fail to achieve is running the same logic from the former stage on the remote EC2 by defining the containerId variable first and running a conditional statement. I get this error:

bash: -c: line 1: syntax error near unexpected token `('
bash: -c: line 1: `def containerId = sh(script: \"docker ps --quiet --filter name=$CONTAINER_NAME\", returnStdout: true).trim()'

I tried encapsulating with single quotes and escaping but it did not work or my lack of knowledge hinders me to understand the right approach.

Any help would be much appreciated.

p.s. I am new to the SE world and still learning.


Solution

  • After further tinkering I changed the logic and resorted to a workaround by simply executing a wget command in the jenkins file, which pulls a bash script from git and executes all needed commands.

    Not really a direct answer to the question, but bottom line enables what I wanted to achieve. I also simplified the commands by utilizing docker-compose.

    Jenkins stage:

            stage('Deploy Docker container on EC2') {
            steps {
                script {
                    sshagent(['aws-ssh']) {
                        echo "Deploying Docker container on EC2  ..."
                        sh "ssh -o StrictHostKeyChecking=no ec2-user@35.157.110.150 'bash -c \"\$(wget -qLO - https://raw.githubusercontent.com/juronja/DiluteRight/refs/heads/main/ec2-commands.sh)\"'"
                    }
                }
            }
        }
    

    bash script:

    #!/bin/bash
    
    # Downloading and overwriting the compose file
    wget -O compose.yaml https://raw.githubusercontent.com/juronja/DiluteRight/refs/heads/main/compose.yaml
    
    # Stoping and starting the container
    docker-compose down
    docker-compose up -d