# Part 3: Jenkins + SSH Remote Execution

### Jenkins CI/CD Series

| Part | Article |
| --- | --- |
| 1 | [Install Jenkins with Docker](https://ask-abhi.com/part-1-install-jenkins-with-docker) |
| 2 | [Creating Your First Jenkins Pipeline](https://ask-abhi.com/part-2-creating-your-first-jenkins-pipeline) |
| 3 | [Jenkins SSH Remote Execution](https://ask-abhi.com/part-3-jenkins-ssh-remote-execution) |
| 4 | [Automating MySQL Backup to AWS S3](https://ask-abhi.com/part-4-automating-mysql-backup-to-aws-s3) |
| 5 | [Making Jenkins Automation Scalable](https://ask-abhi.com/part-5-making-jenkins-automation-scalable) |
| 6 | [Running Ansible from Jenkins](https://ask-abhi.com/part-6-running-ansible-from-jenkins) |
| 7 | [Jenkins Pipeline from GitHub](https://ask-abhi.com/part-7-control-jenkins-pipeline-through-github) |
| 8 | [Multibranch Pipelines](https://ask-abhi.com/part-8-multibranch-pipelines) |
| 9 | [Parameterized Pipelines](https://ask-abhi.com/part-9-parameterized-pipelines) |
| 10 | [Environment Variables in Pipelines](https://ask-abhi.com/part-10-environment-variables-in-pipelines) |

* * *

### Goal

The goal of this project is to extend the Jenkins environment created in **Part 1** by integrating it with a remote server through **SSH (Secure Shell)**. In this exercise, we will create a container that acts as a remote host with an SSH server and configure Jenkins to securely connect to it.

By the end of this project, Jenkins will be able to execute commands and scripts on a remote machine, enabling automation tasks such as running scripts, managing servers, and performing deployment-related operations.

* * *

### Purpose

The purpose of this exercise is to demonstrate how Jenkins can interact with external systems through SSH. In real-world DevOps environments, Jenkins often needs to run commands on remote machines to perform operations such as application deployment, server configuration, and maintenance tasks.

By creating a dedicated SSH-enabled container and integrating it with Jenkins, we simulate a typical automation scenario where Jenkins acts as the orchestration tool while executing commands on remote infrastructure.

This setup helps us to understand how Jenkins communicates with remote systems securely using SSH keys and credentials, which is a fundamental concept in building automated CI/CD pipelines.

* * *

### Prerequisites

Before starting this project, ensure the following requirements are completed:

*   Ready to use `Host` and the `directory` structure to run `Dockerfiles` and `docker-compose.yml` (Refer to [Part 1)](https://ask-abhi.com/part-1-install-jenkins-with-docker)
    
*   Access to the Jenkins dashboard with administrative privileges.
    

* * *

### Step-by-Step Implementation

The purpose of the SSH server is to run shell commands or scripts on other servers

The directory should look like this:

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/5e5482c6-7f97-42f8-81ec-09d3d04f5bf9.png align="center")

> Note- Since we are using Docker, we will use Dockerfiles or images available on Docker Hub.

**Create Containers**

**Jenkins** - will download the latest image from Docker Hub  
**SSH server** - Customized Dockerfile (name: remote-host)

*   Create a Dockerfile in the directory `jenkins/jenkins_home/centos7`
    

> Note- centos7 is just random directory name I used

`Dockerfile`

```yaml
FROM rockylinux:9

RUN dnf install -y openssh-server passwd sudo && dnf clean all

RUN useradd -m remote_user && \
    echo "remote_user:1234" | chpasswd

RUN mkdir -p /home/remote_user/.ssh

COPY remote-key.pub /home/remote_user/.ssh/authorized_keys

RUN chown -R remote_user:remote_user /home/remote_user/.ssh && \
    chmod 700 /home/remote_user/.ssh && \
    chmod 600 /home/remote_user/.ssh/authorized_keys

RUN sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config

RUN ssh-keygen -A

EXPOSE 22

CMD ["/usr/sbin/sshd","-D"]
```

*   **The YAML will create two containers, and I have placed it at** `jenkins/jenkins_home/`
    

`docker-compose.yml`

```yaml
services:
  jenkins:
    container_name: jenkins
    image: jenkins/jenkins
    ports:
      - "8080:8080"
    volumes:
      - $PWD/jenkins_home:/var/jenkins_home
    networks:
      - net
  remote_host:
    container_name: remote-host
    image: remote-host
    build:
      context: centos7
    networks:
      - net
networks:
  net:
```

*   **Build the remote-host image for the SSH server**
    

```plaintext
docker compose build
```

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/4926b00e-bfe2-4ce6-9ea6-86b316191e5f.png align="center")

*   **Verify Image**
    

```plaintext
docker images
```

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/2c4ecd99-9bbb-4f30-94a5-24741d1a8b25.png align="center")

*   **Create containers by using the docker-compose.yml file from** `jenkins/jenkins_home/`
    

```plaintext
docker compose up -d
```

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/b7c9d998-29e6-4e32-9ee0-ef3ab823e403.png align="center")

*   **Verify containers with** `docker ps`
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/77680176-f4df-4d99-917e-b0a68df99bb4.png align="center")

*   **Log in to Jenkins**
    

> Note - host\_ip:8080
> 
> By using the credentials you created (Refer First part of this article if needed)

*   **Go to Manage Jenkins--> Plugins and install the <mark class="bg-yellow-200 dark:bg-yellow-500/30">SSH</mark> plugin**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/53865929-7be2-4049-b878-443c05692d1c.png align="center")

*   **Go to Manage Jenkins --> Credentials --> SSH Username with Private key**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/efddc612-4cf4-4e50-840a-a6f61af8e4dd.png align="center")

*   **Add username** `remote-user` **and copy the private key as a remote key below**
    

> Note- This is created part of docker compose and placed in container context (centos: it will act like persistant volume for remote-host container)

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/bb623bd2-935a-4a16-9d7e-50674aa247e4.png align="center")

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/3fb8c164-fcd9-4294-9505-ea1dc0ce3163.png align="center")

*   **Go to** `Manage Jenkins` **\-->** `SSH Servere` **and add details of our SSH server and** `Check connection`
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/a0df1038-02a9-4eaa-93b3-ab37774656a9.png align="center")

> here: Integration completed

*   **Let's test by creating a Freestyle project and testing**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/7bf982db-f798-4a28-979f-661dad2fe7d5.png align="center")

*   **Go to Build Steps and add Execute shell script on remote host using SSH**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/8f2b6fbb-2576-4773-81e0-ab0956354160.png align="center")

*   **Select our user details from the drop-down,**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/aca8be4a-628f-4d62-938a-85704d9dd1a1.png align="center")

*   **Verify if this Job Runs the command on the remote-host and creates a file**
    

**Click** `Build now` **and check** `console output` **from Job number**

*   **Logs**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/aa6bc4ad-4385-47c7-8833-4332e8215a73.png align="center")

*   **Verify if the file has been created or not on the** `remote-host`
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/78ec8a4e-a50e-46ea-8b44-a9b7fd92b143.png align="center")

### Done!!!

* * *

### Conclusion

In this part of the series, we successfully created a remote server container running an SSH service and integrated it with Jenkins. We configured Jenkins to securely connect to the remote host using SSH credentials and executed commands on the remote system through a Jenkins job.

This setup demonstrates how Jenkins can control external infrastructure and automate tasks beyond its own environment. Remote command execution is widely used in DevOps pipelines for tasks such as application deployment, server maintenance, configuration management, and system monitoring.

With this integration in place, Jenkins is now capable of orchestrating tasks across multiple systems, which is a critical capability for modern CI/CD automation.

In the next part of the series, we will build on this foundation by creating a **real-world automation workflow where Jenkins performs a MySQL database backup and uploads it to AWS S3 automatically**.

* * *

## 🔗 Continue the Series

⬅️ **Previous Article:** [Part **2 Creating Your First Jenkins Pipeline**](https://ask-abhi.com/part-2-creating-your-first-jenkins-pipeline)  
➡️ **Next Article:** [Part 4 Automating MySQL Backup to AWS S3](https://ask-abhi.com/part-4-automating-mysql-backup-to-aws-s3)

* * *

⭐ If you found this article useful, follow **https://ask-abhi.com** for more DevOps tutorials.

* * *
