Project-2: Jenkins Declarative Pipeline: Deploying and Automating the 2048 Game
Day 81: #90DaysOfDevOps Challange
Table of contents
- What is a Pipeline in Jenkins? ๐ง๐
- Why Use Declarative Pipeline Syntax? ๐ก๐ป
- What is CI/CD? ๐๐ป
- What Is a Build Job? ๐๐ทโโ๏ธ
- Setting Up Jenkins on an AWS EC2 Instance Running Ubuntu: ๐โ๏ธ
- Creating a Dockerfile and Docker Compose File for the 2048 Game: ๐ณ๐ฆ
- Deploying the Application Using a Declarative Pipeline: ๐๐ง
- Code Availability: ๐ป๐
- Conclusion: ๐โจ
Jenkins, an open-source automation server, plays a vital role in enabling continuous integration and continuous delivery (CI/CD) for software development projects. Among the powerful features Jenkins offers, the Declarative Pipeline Syntax stands out. This tutorial will guide you through the creation of a Jenkins job using the Declarative Pipeline Syntax, using the popular 2048 game as an interesting example. Let's dive in!
What is a Pipeline in Jenkins? ๐ง๐
A pipeline in Jenkins is a collection of interconnected steps or jobs that execute sequentially. It serves as the foundation for the "Pipeline-as-code" approach, allowing the CD pipeline to be versioned and reviewed like any other code. The pipeline's definition is written in a text file called a Jenkinsfile, which can be committed to the project's source control repository.
Why Use Declarative Pipeline Syntax? ๐ก๐ป
Declarative Pipeline Syntax is a more recent and advanced implementation of pipelines as code. It offers a structured and opinionated way of defining pipelines. Its concise and readable syntax simplifies pipeline creation, making it easier for developers to understand and modify pipelines. By committing the Jenkinsfile to source control, you gain immediate benefits such as creating a Pipeline build process for all branches and pull requests and facilitating code review and iteration on the Pipeline along with the remaining source code.
What is CI/CD? ๐๐ป
CI/CD, which stands for Continuous Integration/Continuous Delivery (or Continuous Deployment), is an essential software development approach that automates and streamlines the process of building, testing, and deploying code changes.
Continuous Integration (CI) involves regularly merging code changes from multiple developers into a shared repository, where automated builds and tests are run to detect issues and conflicts early on.
Continuous Delivery (CD) goes a step further, automatically deploying code changes to production environments after thorough testing and validation. This ensures that the code is always ready for release to end-users without delays or manual intervention.
Continuous Deployment (CD) automates the release process, pushing code changes to production as soon as they pass all tests and checks.
What Is a Build Job? ๐๐ทโโ๏ธ
In Jenkins, a build job encompasses the configuration for automating a specific task or step in the application-building process. These tasks include gathering dependencies, compiling, archiving, transforming code, and testing and deploying code in different environments. Jenkins supports various types of build jobs, such as freestyle projects, pipelines, multi-configuration projects, folders, multibranch pipelines, and organization folders.
Setting Up Jenkins on an AWS EC2 Instance Running Ubuntu: ๐โ๏ธ
Let's start by setting up Jenkins on an AWS EC2 instance running Ubuntu. Follow these steps:
1๏ธโฃ Launch an AWS EC2 instance with Ubuntu as the operating system. Ensure that port 8080 is open for Jenkins, and port 80 is open for the application in the security group.
2๏ธโฃ Once the instance is launched and running, log in to the instance using SSH.
3๏ธโฃ Install Java, Jenkins, and Docker by running the provided commands in the terminal.
sudo apt update
sudo apt install openjdk-11-jre
java -version
curl -fsSL https://pkg.jenkins.io/debian/jenkins.io-2023.key | sudo tee \
/usr/share/keyrings/jenkins-keyring.asc > /dev/null
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
https://pkg.jenkins.io/debian binary/ | sudo tee \
/etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update
sudo apt-get install jenkins
sudo apt install docker.io
sudo usermod -aG docker jenkins
sudo systemctl restart jenkins
4๏ธโฃ Start Jenkins using the provided command.
sudo systemctl start jenkins
5๏ธโฃ Access Jenkins in a web browser by navigating to http://<instance_ip>:8080 and follow the on-screen instructions to set it up.
Copy this string and paste it in the administrator password
Creating a Dockerfile and Docker Compose File for the 2048 Game: ๐ณ๐ฆ
To build and run the 2048 game application, we'll create a Dockerfile and a docker-compose.yml file. Here's how:
1โฃ Create a Dockerfile in the root directory of your project and add the provided content.
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y nginx zip curl
RUN sed -i '/daemon off;/d' /etc/nginx/nginx.conf
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
RUN curl -o /var/www/html/master.zip -L https://github.com/gabrielecirulli/2048/archive/master.zip
RUN cd /var/www/html/ && unzip master.zip && mv 2048-master/* . && rm -rf 2048-master master.zip
EXPOSE 80
CMD ["nginx", "-c", "/etc/nginx/nginx.conf"]
2๏ธโฃ Create a docker-compose.yml file in the root directory of your project and add the provided content.
version: "3.8"
services:
nginx:
build:
context: .
dockerfile: Dockerfile
ports:
- "80:80"
3๏ธโฃ Build and run the application using the provided commands.
sudo docker build . -t myapp
sudo docker run -d -p 80:80 --name myapp myapp
Deploying the Application Using a Declarative Pipeline: ๐๐ง
Now, let's deploy the 2048 game application using a declarative pipeline. Follow these steps:
1๏ธโฃ Create a new Jenkins pipeline job and configure it as described.
2๏ธโฃ Enter the provided pipeline script in the pipeline configuration.
pipeline {
agent any
stages {
stage('Clone') {
steps {
script {
// Check if repository directory exists
if (!fileExists('/var/lib/jenkins/workspace/2048_deployment/2048_game_deployment')) {
sh 'git clone https://github.com/Dhananjaykul/2048_game_deployment.git'
} else {
echo 'Repository already cloned'
}
}
}
}
stage('Build') {
steps {
dir('/var/lib/jenkins/workspace/2048_deployment/2048_game_deployment') {
sh 'docker build -t myapp .'
}
}
}
stage('Deploy') {
steps {
dir('/var/lib/jenkins/workspace/2048_deployment/2048_game_deployment') {
script {
sh 'docker stop myapp || true'
sh 'docker rm myapp || true'
sh 'docker run -d -p 80:80 --name myapp myapp'
}
}
}
}
stage('Test') {
steps {
dir('/var/lib/jenkins/workspace/2048_deployment/2048_game_deployment') {
script {
def ec2PrivateIP = sh(returnStdout: true, script: "curl -s http://169.254.169.254/latest/meta-data/local-ipv4").trim()
sh "curl -s http://${ec2PrivateIP}:80" // Make a GET request to the application
sh "curl -s http://${ec2PrivateIP}:80 | grep '2048'" // Verify that the response contains "2048"
}
}
}
}
}
}
3๏ธโฃ Save the pipeline configuration.
4๏ธโฃ Run the pipeline job by clicking "Build Now."
5๏ธโฃ Verify the deployment by accessing the application in a web browser using the EC2 instance's public IP address and port 80.
Code Availability: ๐ป๐
The code for this project, including all necessary files and documentation, is available on GitHub. Feel free to fork the repository and make modifications to suit your needs. The repository can be found here.
Conclusion: ๐โจ
In this tutorial, we explored the Jenkins Declarative Pipeline Syntax and its significance in automating CI/CD processes. We successfully deployed the 2048 game application using Docker and Jenkins, and then automated the deployment using a declarative pipeline. By following the steps outlined in this blog, you can gain hands-on experience in setting up Jenkins, building Docker images, deploying applications, and automating the entire process. Enjoy exploring the possibilities of Jenkins Declarative Pipelines in your own projects!