Execute bash script on a remote host using Jenkins Pipeline and Publish Over SSH plugin

Rina Villaruz
4 min readFeb 5, 2024

--

I decided to install Jenkins on another server because I don’t want it to mess up with my containers and I will execute different remote scripts from different servers.

Prerequisite: A running Docker and Docker Compose, a DNS record that points to https://jenkins.yourdomain.com, and knowledge of SSH keys.

Let’s install Jenkins first by creating a Docker Compose file.

version: '3.8'
services:
jenkins:
image: jenkins/jenkins:lts
ports:
- 80:8080
container_name: jenkins
restart: always
volumes:
- .:/var/jenkins_home

The file states that it will pull the latest Jenkins image from Docker Hub and assign it to port 80 so that we don’t need to type https://jenkins.yourdomain.com:8080 in the browser.

Make sure to have the restart: always because when you install any Jenkins plugins, the service will automatically restart, and you will lose connection to the container.

From the Jenkins server, copy the public key and save it to the authorized keys of the remote server server.

Jenkins Server: cat ~/.ssh/id_rsa.pub

Go to Dashboard > Manage Jenkins and click on the Plugins section.

Install Publish Over SSH Version plugin.

Let’s add the private key and passphrase from the remote server. On your Name, click the drop-down and you will see the Credentials.

Click the + Add Credentials blue button.

Choose the SSH Username with the private key as Kind, Global as Scope, enter any ID or leave it blank, your username, and the Private key and passphrase from the remote server.

To get the Private key, ssh to your remote server and execute the command: cat ~/.ssh/id_rsa. Don’t forget to enter the passphrase if there is any.

Let’s create a Pipeline. On the Dashboard, click + New Item.

Enter the pipeline’s name, choose Pipeline as the type of project, and click OK.

Once saved, scroll down to the Pipeline section. Copy and paste the following script:

pipeline {
agent any

stages {
stage('Build') {
steps {
echo 'Building..'
sshagent(['production']) {
sh "ssh -o StrictHostKeyChecking=no -l root 127.0.0.1 'cd ~/public_html && ./bash_script.sh'"
}
}
}
}
}

The production in sshagent([‘production’]) comes from the Credentials that we made.

Specify the user, the IP address of the server, and the bash script to be executed.

Click the Build Now to start the building process. Go to Console Output and you will see something like this:

Started by user Rina
Resume disabled by user, switching to high-performance, low-durability mode.
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /var/jenkins_home/workspace/production
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Build)
[Pipeline] echo
Building..
[Pipeline] sshagent
[ssh-agent] Using credentials root
[ssh-agent] Looking for ssh-agent implementation...
[ssh-agent] Exec ssh-agent (binary ssh-agent on a remote machine)
$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-XX/agent.xxx
SSH_AGENT_PID=1234
Running ssh-add (command line suppressed)
Identity added: /var/jenkins_home/workspace/production@tmp/private_key_123.key (root@127.0.0.1)
[ssh-agent] Started.
[Pipeline] {
[Pipeline] sh
+ ssh -o StrictHostKeyChecking=no -l root 127.0.0.1 cd ~/public_html && ./bash_script.sh
This is a test script from the remote host.
[Pipeline] }
$ ssh-agent -k
unset SSH_AUTH_SOCK;
unset SSH_AGENT_PID;
echo Agent pid 123 killed;
[ssh-agent] Stopped.
[Pipeline] // sshagent
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

The build is successful if there is a Finished: SUCCESS at the bottom of the Console Ouput.

--

--

Rina Villaruz

I am a DevOps Engineer specializing in Docker and Kubernetes. During my spare time, I play around with Objective-C.