Deploying your project from GitHub to VPS using Jenkins for CI/CD
Streamline Your Deployment Workflow with Jenkins, GitHub, and VPS Integration
Deploying your project from GitHub to VPS using Jenkins for CI/CD
Introduction
In this quick tutorial, I’ll show you how I implemented CI/CD in my Nextjs 14 project on my new VPS server. This blog post is also valid for react projects or applications using nodejs. So you might want to ask, what is Jenkins or CI/CD? So you have pushed your fancy little project to your new VPS server, but you need a way to continually push updates/fixes to your application, that is where Jenkins come in for Continuous Integration/Continuous Delivery (CI/CD).
HEADS UP: An ideal hardware requirement for this is a VPS with at least 2gb of ram. Anything lower than that? you may run into memory issues during build processes. This is a step by step tutorial, please follow religiously.
Getting a VPS server
If you are yet to purchase a VPS, you can quickly purchase from one these cloud providers. But I would recommend getting one (here). It’s cheap and very easy to get started. After signing up, your new VPS credentials (ip address and login) will be sent to your email address.
Initial Server Setup
First, SSH into your server
ssh root@your_server_ip
Create a New User
You may want to create a new user, if you prefer.
adduser your_username
Add user to sudo group
usermod -aG sudo your_username
Switch to the new user
su - your_username
Basic Security Setup
Update system packages
sudo apt update & upgrade -y
Install git and setup firewall
sudo apt install -y curl git ufw
Configuring the firewall to allow some ports we’ll need
sudo ufw allow OpenSSH
sudo ufw allow 80
sudo ufw allow 8080
sudo ufw allow 443
sudo ufw enable
Install Node and PM2
We’ll be using nodejs for our Next.js deployment) and PM2 for production process management, you can read more about pm2 here
# Install Node.js using nvm (Node Version Manager)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
source ~/.bashrc
# Install Node.js LTS version
nvm install --lts
# Install PM2 globally
npm install -g pm2
Install & Configure Nginx
# Install Nginx
sudo apt install nginx -y
# Start Nginx
sudo systemctl start nginx
sudo systemctl enable nginx
Let’s create nginx configuration for your app
sudo nano /etc/nginx/sites-available/your-app
Add this to the configuration (replace your-domain.com with your actual domain name):
server {
listen 80;
server_name your-domain.com www.your-domain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Enable this configuration
sudo ln -s /etc/nginx/sites-available/your-app /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
Setup Jenkins
Now let’s install Jenkins and other dependencies
sudo apt update
sudo apt upgrade -y
Install Java (It’s a Jenkins requirement)
sudo apt install openjdk-17-jre-headless -y
Install Jenkins
# Add Jenkins repository
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee \
/usr/share/keyrings/jenkins-keyring.adk > /dev/null
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.adk] \
https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
/etc/apt/sources.list.d/jenkins.list > /dev/null
# Install Jenkins
sudo apt update
sudo apt install jenkins -y
Start and enable Jenkins
sudo systemctl start jenkins
sudo systemctl enable jenkins
Now we need to login to jenkins
Access Jenkins at
http://your_server_ip:8080
Retrieve initial admin password:
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
Install recommended plugins
Create an admin user
Create a file name called
Jenkinsfile
at the root in your GitHub repository and paste the below in it.
pipeline {
agent any
tools {
nodejs "NodeJS"
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Install Dependencies') {
steps {
sh 'npm install'
}
}
stage('Build') {
steps {
sh 'npm run build'
}
}
stage('Deploy') {
steps {
sh '''
pm2 delete app_name|| true
pm2 start npm --name "app_name" -- start
'''
}
}
}
}
Configure GitHub Webhook
In your GitHub repository settings, go to Webhooks
Add a new webhook:
Payload URL:
http://your_server_ip:8080/github-webhook/
Content type:
application/json
Select events: Push and Pull Request events
Configure Jenkins Installation
For setting up Jenkins for our Next.js project, you'll need to configure several key components/plugins
Go to
http://your_server_ip:8080
. On you Jenkins dashboard, Go to "Manage Jenkins" > "Plugins"Install NodeJS Plugin
To configure the nodejs installation, From the dashboard Go to "Manage Jenkins" > "Tools"
Name it (e.g., "NodeJS")
Choose a recent Node.js version
Check "Install automatically"
For other plugins to Install, navigate to "Manage Jenkins" > "Plugins":
Install these:
GitHub Integration Plugin
SSH Agent Plugin (for deployment)
Create a New Pipeline Job
Click "New Item"
Choose "Pipeline"
Configure:
Select “Pipeline"
Choose "Pipeline Script from SCM"
Select “SCM”
Choose “git”
Enter Repository URL
For Credentials, click “add” button
Enter your giithub username
The password should be your github token. see how to create one here (Ensure you check webhook while creating your token): (https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)
Specify your production branch (main/master/production), whatever works for you.
Apply changes and save
Once you are sure everything is set up, now click on “build now”. This is will execute everything you have in the
Jenkinsfile
. You can check the “Console Output” for the steps it run.
Starting the Application
To view the Jenkins cloned project
cd /var/lib/jenkins/workspace
# View it's content
ls -1
Start the application
pm2 start npm --name "your_app_name"
Voila! Your app is now running and can be accessed at http://your_server_ip:3000
Conclusion
Thank you for reading to this point, I hope you were able to successfully configure and deploy your application. Keep building and deploying. Until next time, happy coding. ✌🏼
If you have questions, please feel free to drop them in the comments, I’ll do my best to send a response ASAP