CI/CD Pipeline using Jenkins and Gogs

What is CI/CD?

Nowadays, the concept of the CI/CD is everywhere. CI stands for continuous integration and the CD stands for Continuous Deployment. CI/CD is the backbone of the DevOps environment. It helps organisations to speed up the release of small features in new software, and implement the feedback and changes quickly.

Gogs is a free and open source Git service written in Go language. painless self hosted Git service. You can install and configure Gogs on your own servers. It supports all platforms including Linux, Mac and Windows. For more about Gogs, check their official document https://gogs.io/docs

Jenkins is a self-contained open source automation platform which can be used to automate all kinds of software development, testing, and distribution, or deployment tasks.

In this tutorial, I will show you how to create a simple CI/CD Pipeline using Jenkins and Gogs In this scenario, we have hosted a django application on the linux server. As of now we are doing the following process if any changes needed for the application. Developer pulls the live code from the Gogs repository and pushes back to the repo after modifying the code. Then the SystemAdministrator will pull the latest code from the Gogs repo to the application server.

We can automate the above processes with the help of CI/CD.

1. Developer push/merge code into a branch in the repo.

2. Admin get a notification message in slack about the push

3. Gogs trigger the Jenkins job for the new build and initiate the build if the conditions satisfy that specified in the Jenkins.

4. Admin get a notification message after the build.

5. Once the build is completed, the jenkins will trigger the code deployment into the application server.

6. Finally the application server will pull the latest code from the Gogs repo and send a notificatification message to slack. 


CI/CD Pipeline using Jenkins and Gogs img 1
You may get a clear picture about this CI/CD Pipeline using Jenkins and Gogs from the above diagram.

Requirements:

SSH access to Jenkins server.
Gogs admin access.
SSH access to the application server.


1. Install plugins on Jenkins.

Required plugins:
Git
Gogs
Login to your Jenkins web interface.
Go to Plugins Manage

CI/CD Pipeline img2

Search required plugins from there and click on “ Download now and install after restart”

2. Configure webhook


We need a hook to trigger from Gogs to Jenkins job. I’m using a post-receive hook in the repository to poke Jenkins jobs when a new push occurs. In Gogs repo there is a Git Hook option to configure post-receive hook. This hook will help you to minimize the delay between a push and a build. CI/CD Pipeline using Jenkins and Gogs will do this, go to your Gogs repo >> Settings >> Git Hooks >> Post Receive Then add the following line in your hooks. curl http://yourjenkinsserver/git/notifyCommit?url=<URL of the Gogs repo>

 Jenkins and Gogsimg3
using Jenkins and Gogsimg4

3. Configure access to Gogs from Jenkins.

SSH

Login to your jenkins server through ssh and generate a ssh key.

# ssh-keygen


The ssh private and public key will be generated in /var/jenkins_home/.ssh/ Copy that public key from there.

# cat /var/jenkins_home/.ssh/id_rsa.pub


Login to your Gogs and go to your Repository Settings > Deploy keys Add previously copied public key here

 using Jenkins and mg 5

Add this private key in Jenkins credentials.

Login to your jenkins server and go to:

Jenkins >> Credentials >> System >> Global credentials

Then select “SSH username with private key” from the Drop down menu. Enter Gogs ssh username and paste previously created private key there.

Jenkins and Gogs img6

Username and password

You can also configure this with your Gogs username and password.

Go to Jenkins >> Credentials >> System >> Global credentials

Enter your Gogs user username and password there.

CI/CD Pipeline using

4. Configure SSH access to application server from jenkins.

In this example I have a user called jenkins in the application server.

Login to your Jenkins server through SSH.

Copy previously created key to the application server

# ssh-copy-id jenkins@192.168.1.35


Now configure this ssh details in jenkins.

Install “Publish over SSH” plugin

Gogs img8

Go to Jenkins > Manage Jenkins > Configure System > Publish Over SSH




Jenkins and img9

If you get any error as shown in the below screenshot, create ssh key with following options in the 3rd step.


# ssh-keygen -t rsa -b 4096 -m PEM

Pipeline using img10

5. Configure Jenkins job


Login to your Jenkins dashboard.
Go to Jenkins > New Item.
Enter your project name and select “Free style project”

 Jenkins and Gogs img11

In this job, we are executing a bash script to deploy the code into the application server. So we need string parameters to pass into the bash script as a argument.

So select the option “This project is parameterised” under Gogs webhook

Then add the parameter “ GIT_FOLDER”

Specify the directory name in the application server to which git pull happens for code deployment.

In my case the directory is /home/jenkins/cicd-dev

 Pipeline   img12

Add next parameter is “GIT_CHECKOUT_DIR”

Specify the directory name in the application server to which will deploy the code.

CI/CD  img13

Next parameter is “SERVER_ENV”

CI/ img14

Next parameter is “VENV”

Specify your python virtual environment path in the application server.

CI/CD Pipeline img15


Then add the parameter “DEPLOY_SCRIPT”

This variable stores the path of the deploy script.

hsgfhsg

CI/CD  using  and Gogs img16

I will show you the content of the script at the end of the tutorial.

Now add the Gogs repo URL and credentials in the “Source Code Management” You can select previously added credentials from there.

CI/CD Pipeline  Jenkins and  img17

Finally go to the “Post-build Action” in the Jenkins job.

Select “Send build Artifacts over SSH” and paste the following command in the “Exec command box”

cd $GIT_FOLDER && git fetch && if ! (git diff –exit-code –name-only $GIT_BRANCH — $DEPLOY_SCRIPT); then git pull;fi && bash $DEPLOY_SCRIPT  $GIT_FOLDER $GIT_BRANCH $GIT_CHECKOUT_DIR $GIT_URL $SERVER_ENV $VENV

CI/CD Pipeline Gogs img18

If the conditions satisfy, jenkins will pull files from the gogs repo and execute the deploy script with the above mentioned arguments.
Here is the deploy script written in the bash script.


###Beginning##
#!/bin/bash
#Deployment script used by Jenkins
#Author: Hans Emmanuel
GIT_FOLDER=$1
GIT_BRANCH=$2
GIT_CHECKOUT_DIR=$3
GIT_URL=$4
SERVER_ENV=$5
VENV=$6
PIP_INS=false
DEPLOYED=false
SLACK_URL=  <specify your slak url if you are using slack>


cd $GIT_FOLDER
git fetch
if (git cat-file -e $GIT_BRANCH:DEPLOY)
then
echo “deploying the code”
BRANCH=$(echo ${GIT_BRANCH} | cut -d’/’ -f2)
 if ! (git diff –exit-code –name-only $GIT_BRANCH — requirements.txt)


then
         PIP_INS=true

fi
git pull && GIT_WORK_TREE=$GIT_CHECKOUT_DIR git checkout $BRANCH  -f && DEPLOYED=true && echo “CODE Deployed”


 cd $GIT_CHECKOUT_DIR
     if $PIP_INS
then
cd $GIT_CHECKOUT_DIR
echo “Installing requirements”
source $VENV/bin/activate
pip install -r requirements.txt


fi
touch $GIT_CHECKOUT_DIR/uwsgi.ini
url=$GIT_URL
REPO=$(basename $url)
if $DEPLOYED
then
curl -X POST –data “payload={\”text\”: \”:slack: Jenkins Repo $REPO branch ${GIT_BRANCH} Deployment is SUCCESS on ${SERVER_ENV} server\”}” $SLACK_URL


else
curl -X POST –data “payload={\”text\”: \”:slack:  Jenkins Repo *$REPO* branch *${GIT_BRANCH}* Deployment is *FAILED* on *${SERVER_ENV}* server\”}” $SLACK_URL

fi
else echo “NOT Deploying Code”
fi


###End of the Script###

Leave a Reply

Your email address will not be published. Required fields are marked *