Project Assessment – Vananam Tasks: -
- Containerization: • Create a Dockerfile to containerize the above application. • Ensure the container runs the web server on port 8080. • Provide a docker-compose.yml file if needed for any multi-container setup.
- Continuous Integration Setup: • Choose a CI tool (e.g., Jenkins, GitHub Actions, GitLab CI). • Create a pipeline that: • Triggers on every git push to the main branch. • Builds the Docker image. • Runs any tests (you can include a dummy test for demonstration).
- Continuous Delivery Setup: • Use the same or a different tool to manage CD (e.g., Jenkins, Spinnaker, ArgoCD). • Setup the CD pipeline to: • Deploy the Docker container to a simulated staging environment upon successful CI build. • Provide rollback capabilities in case deployment fails.
Project Overview: - Project Name: Simple web application in CI/CD pipeline Delivery Platform: Jenkins Project Components and Pipeline Jenkins Files: This application own Jenkins File defining the steps for building, testing, and deploying the service Docker: Microservices are containerized using Docker, allowing for consistent environments from development to production.
GitHub Repository Link: - Continuous Integration GitHub –webhook Jenkins Docker Continuous Delivery Docker containerization
PHASE 1: Infrastructure Setup Launch virtual Machine using AWS EC2: Here is a detailed list of the basic requirements and setup for the EC2 instance I have used for running Jenkins, including the specific instance type, AMI, and Security groups. EC2 instance requirement setup:
- Instance Type:
- Type: t2.medium
- vCPUs:
- Memory: 4GB
- Network Performance: Moderate
- Amazon Machine Image (AMI)
- AMI: ubuntu Server 22.04 LTS (HVM)
- Security Groups Security groups act as a virtual firewall for your instance to control inbound and outbound traffic. Screenshot of SG:
After Launching your virtual machine, SSH into the server.
Install Jenkins, Docker on VM Server
Execute the commands on the server.
#! /bin/bash
#Install OpenJDK 17 JRE
sudo apt update -y
sudo apt install fontconfig openjdk-17-jre -y
#Download Jenkins GPG key
sudo wget -O /usr/share/keyrings/jenkins-keyring.asc
https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
#Add Jenkins repository to package manager resource
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc]"
https://pkg.jenkins.io/debian-stable binary/ | sudo tee
/etc/apt/sources.list.d/jenkins.list > /dev/null
#Update package manager respositories
sudo apt-get update -y
#Install jenkins
sudo apt-get install jenkins -y
java -version
jenkins --version
Save this script in a file, for example, install_jenkins.sh, and make it executable using: chmod +x install_jenkins.sh then you can run the script using: ./install_jenkins.sh This script will automate the installation process of OpenJDK 17 and Jenkins
Screenshot of Install
Phase 2: Create a Jenkins Pipeline Step 1: Install Jenkins plugins To get started, you need to install the required Jenkins plugins. Follow these steps to install the plugins. Access Jenkins Dashboard: Open a web browser and navigate to your Jenkins instance (e.g., http://your-instance-public-dns:8080). Log in with your Jenkins credentials. (cat address provided on Jenkins) As per project requirement container must run on port 8080, in mean while Jenkins port also 8080, so we have to change the Jenkins port number from access following steps.
- Open the /usr/lib/systemd/system/Jenkins.service file.
- After open this file under Environment section, you can change the port like this HHTP_PORT=8100
- Then you should restart Jenkins with sudo systemctl daemon reload
- Then check the status use this command sudo systemctl restart Jenkins.service
Screenshot for change port number of Jenkins
Install Plugins: -Go to Manage Jenkins Manage Plugins -Click on the Available tab. Search for and install the following plugins: • Docker: Enables Jenkins to use Docker containers. • Docker Pipeline: Allows Jenkins to use Docker containers in pipeline jobs. • NodeJS: Allows to create as many NodeJS installations. Screenshot of plugin
Step 2: Create Credentials You need to create credentials for Docker and GitHub access. Create Docker Credentials: -Go to Manage Jenkins Manage Credentials (global) Add Credentials. -Choose Username with password as the kind. -ID: docker-cred -Username: Your Docker Hub username. -Password: Your Docker Hub password. -Click OK.
Screenshot of Docker Cred
Create GitHub Credentials: -Go to Manage JenkinsManage Credentials (global) Add Credentials. -Choose Secret text as the kind. -ID: git-cred -Secret: Your GitHub Personal Access Token. -Click OK. Screenshot of Git cred
Step 3: Install NodeJS and Docker on Jenkins -Go to Manage Jenkins Tools. -Navigate down NodeJS installations add NodeJS -Name: nodejs10 -then select Install automatically then leave the other settings as in Jenkins -Navigate down Docker Installations add Docker -Name: docker -then select Install automatically Download from docker.com then leave the remain settings as Jenkins -Click apply and save. Screenshot of Nodejs and Docker tools config
Step 4: Create a Jenkins pipeline Stage 1: Git SCM checkout This is the first step in the CI/CD pipeline where the source code is fetched from a Git repository. This stage ensures that the latest codebase is used for each build. Stage 2: Install Project Dependencies Install project specific dependencies using package managers like npm (for Node.JS). Install Node.js dependencies using npm install. Stage 3: Build Docker Image and Push into Docker Hub Repo Package the application into a Docker image for containerized deployment. Create Dockerfile specifying image configuration. Build Docker image using Docker build command. Push the built Docker image to a Docker Hub repository for centralized storage and distribution. Steps:
- Authenticate with Docker Hub.
- Push Docker image to designated repository Stage 4: Deploy application to Docker container Deploy the application from creating Docker container and port forwarding into 3000 for see the output. Verify the successful deployment of the application to the containerization. Here’s a declarative Jenkins pipeline script for the described stages: Screenshot of Jenkins code pipeline { agent any tools { nodejs 'nodejs10' } stages { stage('Git checkout') { steps { git branch: 'main', changelog: false, poll: false, url: 'https://github.com/kpselvaips/nodejs_assesment.git' } } stage('Install dependencies') { steps { sh "npm install" } } stage('docker build & push') { steps { script { withDockerRegistry(credentialsId: 'docker-cred', toolName: 'docker') { sh 'docker build -t newimage .' sh 'docker tag newimage kpselvaperiyasamy/nodejsassesment:${BUILD_NUMBER}' sh 'docker push kpselvaperiyasamy/nodejsassesment:${BUILD_NUMBER}' } } } } stage('docker container') { steps { script { withDockerRegistry(credentialsId: 'docker-cred', toolName: 'docker') { sh 'docker run -d --name demo-nodejssample -p 8080:3000 kpselvaperiyasamy/nodejsassesment:${BUILD_NUMBER}' } } } } } }
Screenshot of Output
Step 5: Configure Jenkins Pipeline Save the Jenkinsfile into GitHub -Configure Branch Sources: -Under branch sources, Click Add Source. -Choose Git. Project Repository: Enter the repository URL (?) Credentials: Select the git-cred credentials. Configure Build Configuration: Under Build Configuration, ensure by Jenkinsfile is selected. Script Path: Leave it as the default (Jenkinsfile). Screenshot of path setting
Step 6: Set up GitHub Webhook Go to GitHub Repository Settings: -Navigate to your repository on GitHub. -Go to Settings Webhooks Add Webhook: -Click Add webhook -Payload URL: enter the webhook URL from Jenkins URL (e.g., http://your-jenkins-instance:8080/webhook) -Remain settings leave it as Usual. -Click add webhook. Screenshot of webhook
After Completing this you will see your Jenkins pipeline starts build automatically. Step 6: Edit application file Go to GitHub and make a change of app.js file and commit the changes. Once done commit, then trigger automatically push to build pipeline. Screenshot of make change the file
Final output after commit the changes: Screenshot of final output;