Beginner's Guide: Automating Docker Deployments with Jenkins, Ansible, and GitHub

Beginner's Guide: Automating Docker Deployments with Jenkins, Ansible, and GitHub

Deploying applications manually can be time-consuming and prone to errors. In this blog, I’ll demonstrate how to automate the deployment of Docker containers using Jenkins, Ansible, and GitHub. This step-by-step guide is ideal for beginners exploring DevOps concepts.


What Will You Learn?

By the end of this tutorial, you’ll learn how to:

  • Set up Jenkins for CI/CD.

  • Configure Docker for deployments.

  • Automate the deployment process using an Ansible playbook installed on the Jenkins server.

  • Set up a Jenkins pipeline integrated with GitHub webhooks.


Let’s get started!


Prerequisites Checklist

Before you begin, ensure you have the following:

  • AWS Account: Access to launch EC2 instances.

  • SSH Key: A .pem key file to SSH into EC2 instances.

  • Basic Knowledge: Familiarity with Linux commands, Jenkins, Ansible, and Docker.

  • Software Versions:

    • Jenkins: Latest LTS version

    • Docker: Version 20.10+

    • Ansible: Version 2.9+

    • Python: Version 3.8+ (with pip installed)

  • Network Configuration: Ensure ports 8080 (Jenkins) and 22 (SSH) are open in your EC2 security groups.


Step 1: Setting Up Jenkins

  1. Create an EC2 Instance for Jenkins

    Launch an AWS EC2 instance (Ubuntu) for Jenkins.

    SSH into the instance:

     ssh -i your-key.pem ubuntu@<jenkins-ip>
    
  2. Change the Hostname

    Set a descriptive hostname for clarity:

     sudo hostnamectl set-hostname jenkins
    
  3. Install Jenkins

    Update the system:

     sudo apt update && sudo apt upgrade -y
    

    Install JDK 17 (required for Jenkins):

     sudo apt install openjdk-17-jdk -y
    

    Add Jenkins repository and key:

     wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
     sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
    

    Install Jenkins:

     sudo apt update && sudo apt install jenkins -y
    

    Start Jenkins:

     sudo systemctl start jenkins
     sudo systemctl enable jenkins
    
  4. Access Jenkins

    Modify the EC2 instance’s inbound rules to allow traffic on port 8080.

    Open Jenkins in your browser at http://<jenkins-ip>:8080.

    Use the admin password from:

     sudo cat /var/lib/jenkins/secrets/initialAdminPassword
    

    Install the suggested plugins.


Step 2: Setting Up Docker

  1. Create an EC2 Instance for Docker

    Launch another EC2 instance (Ubuntu).

    SSH into the instance:

     ssh -i your-key.pem ubuntu@<docker-ip>
    
  2. Install Docker

    Update the system:

     sudo apt update && sudo apt upgrade -y
    

    Install Docker:

     sudo apt install docker.io -y
    

    Allow the current user to run Docker without sudo:

     sudo usermod -aG docker ubuntu
    

Step 3: Setting Up Ansible on the Jenkins Server

  1. Install Ansible

    SSH into the Jenkins server and install Ansible:

     sudo apt install ansible -y
    
  2. Install the Python Docker SDK

    On the Jenkins server:

     pip install docker
    
  3. Configure Ansible Inventory

    Open the inventory file:

     sudo nano /etc/ansible/hosts
    

    Add the Docker server’s IP under a group called dockerservers:

     [dockerservers]
     <docker-ip>
    

Step 4: Automating Deployments with Ansible

  1. Generate SSH Keys

    On the Jenkins server, generate an SSH key pair:

     ssh-keygen
    

    Copy the public key to the Docker server:

     cat ~/.ssh/id_rsa.pub
    

    Paste this key into the ~/.ssh/authorized_keys file on the Docker server.

  2. Create a Directory for Playbooks

    On the Jenkins server:

     mkdir playbooks
     cd playbooks
    
  3. Create the Ansible Playbook

    Create a file called deployment.yaml:

     nano deployment.yaml
    

    Add the following content:

     - name: Build and Deploy Docker
       hosts: dockerservers
       gather_facts: false
       remote_user: root
       tasks:
         - name: Stop the running container
           docker_container:
             name: rento_container
             state: stopped
           ignore_errors: yes
    
         - name: Remove the stopped container
           docker_container:
             name: rento_container
             state: absent
           ignore_errors: yes
    
         - name: Build docker image
           docker_image:
             name: rento:latest
             source: build
             build:
               path: ~/project/
             state: present
    
         - name: Create and start a new container
           docker_container:
             name: rento_container
             image: rento:latest
             state: started
             ports:
               - "80:80"
    

Step 5: Setting Up a Jenkins Pipeline

  1. Create a Jenkins Freestyle Project

    Go to the Jenkins dashboard and create a new Freestyle project.

    Add your GitHub repository under Source Code Management.

  2. Add a GitHub Webhook

    In your GitHub repository, go to Settings > Webhooks.

    Add a payload URL:

     http://<jenkins-ip>:8080/github-webhook/
    

    Select Push events and Pull requests.

    Tip: If you don’t already have a project repository, you can use a free project template from Free CSS. Download the template, upload it to your GitHub repository, and use it as the source for your Jenkins pipeline.

  3. Add Build Steps

    In your Jenkins Freestyle project:

    • Go to the project configuration in Jenkins.

    • Scroll to the Build section and select Add Build Step → Execute Shell.

    • Paste the following commands:

        # Clean the project directory on the Docker server
        ssh ubuntu@<docker-ip> rm -rf ~/project/*
      
        # Copy the project files from Jenkins to the Docker server
        scp -r /var/lib/jenkins/workspace/Rento ubuntu@<docker-ip>:~/project
      
        # Run the Ansible playbook to build and deploy
        ansible-playbook /var/lib/jenkins/playbooks/deployment.yaml
      

Replace <docker-ip> with the IP address of your Docker server.


Common Issues and Troubleshooting

  1. Jenkins Won’t Start

    • Check the Jenkins service status:

        sudo systemctl status jenkins
      
    • Look for errors in /var/log/jenkins/jenkins.log.

  2. Ansible SSH Permission Denied

    • Verify the SSH key setup between the Jenkins and Docker servers.
  3. Docker Playbook Errors

    • Ensure the docker Python SDK is installed on the Jenkins server

Conclusion

This guide provides a foundation for automating Docker deployments using Jenkins, Ansible, and GitHub. I’m open to suggestions, feedback, and advice to improve or expand on these steps. Feel free to share your thoughts and let’s continue learning together! 🚀