Amalia Hajarani
Posted on November 30, 2023
Prerequisites
- Installed Node version of: v20.10.0.
- Installed and configured Jenkins. If you want to know how, you can check my post on how to do it in How to: SonarQube Code Coverage in Jenkins with Maven Project, you can leave the steps related to the SonarQube.
- Empty
Jenkinsfile
(assuming you make the project skeleton as I did).
Before doing this tutorial
- Make sure you don't run any services (ExpressJS service, NestJS service, and Front-end service) on your local.
Configuring Jenkins for Node project
- To configure Jenkins for Node, go to your Jenkins UI. Mine is at
http://localhost:8085
. - From
Dashboard
, go toManage Jenkins
which you can find on left navigation bar. - Choose
Plugins
. - Go to
Available plugins
section and typeNodeJS Plugin
. I've already installed the plugin, so I cannot show you the step, but this is the plugin: - Back to
Manage Jenkins
. - Choose
Tools
. - Scroll until you see
NodeJS installations
. Don't mind theedited
, because I already have configured mine. - Choose
Add NojeJS
. You can fill the field like mine. I preferred to use my locally installed Node instead of download it from Jenkins environment: - Click
Save
. - (OPTOPNAL) Check if your NodeJS is correctly configured at Jenkins. Choose
New Item
located aboveManage Jenkins
. - Enter a name something like
test-node-configuration
. ChoosePipeline project
. Then clickOK
. -
In
Pipeline
section, add below script and clickSave
.
pipeline { agent any tools { nodejs 'NodeJS' } stages { stage('Check NPM Version') { steps { bat 'npm version' } } } }
You will get redirected into you newly created project. Click
Build Now
. Then you will see you project being built.
Choose
Console Output
. And you will see some logs. If your Node configured correctly, you will see this on your console output:
Upload .env files from every service to Jenkins
Since we are depending on .env
file for every service, we need to upload it into Jenkins server.
- Go to
Manage Jenkins
. - In
Security
section, chooseCredentials
. - Click
System
onStores scoped to Jenkins
section. - Choose
Global credentials (unrestricted)
. For first
.env
, choose fromexpress-service
.Give it some ID so you won't forget what this is
.env
for. Mine is:customer-express-env
. Don't mind the warning, because I already have it configured.
Click
Create
.Do the same for
.env
innest-service
service andfront-end-service
. I ID'd thenest-service
withcustomer-nest-env
and forfront-end-service
I set the ID ascustomer-react-env
.
Writing Jenkinsfile
This is actually very exciting for me because it is the first time I do CI with Jenkins by writing the Jenkinsfile first. I recommend you to write it in an IDE like Visual Studio Code, and if you use VS Code, I recommend you to install an extension called JenkinsFile Support.
Defining the pipeline
First we are going to create the Jenkinsfile pipeline.
pipeline{
}
Defining agent
Since I don't know much about Jenkins, I define the agent as any
.
agent any
Defining secret environment
Since we need .env
to run all service, we have to provide the credential IDs for all .env
that we already upload on Jenkins Server.
environment {
SECRET_FILE_EXPRESS = credentials("customer-express-env")
SECRET_FILE_NEST = credentials("customer-nest-env")
SECRET_FILE_REACT = credentials("customer-react-env")
}
Defining tool
We have to define the tools to build the project. Which is NodeJS.
tools {
nodejs "NodeJS" // change the NodeJS with the name you give when you configuring tools of NodeJS in Jenkins Server
}
Defining stages
We are going to have few stages.
-
Creating
.env
file for every services.
stage("Create ExpressJs Service ENV"){ steps{ dir("express-service") { script { withCredentials([file(credentialsId: "customer-express-env", variable: "SECRET_FILE_EXPRESS")]) { writeFile file: '.env', text: readFile(file: "${SECRET_FILE_EXPRESS}") } } } } } stage("Create NestJs Service ENV"){ steps{ dir("nest-service") { script { withCredentials([file(credentialsId: "customer-nest-env", variable: "SECRET_FILE_NEST")]) { writeFile file: '.env', text: readFile(file: "${SECRET_FILE_NEST}") } } } } } stage("Create React Service ENV"){ steps{ dir("front-end-service") { script { withCredentials([file(credentialsId: "customer-react-env", variable: "SECRET_FILE_REACT")]) { writeFile file: '.env', text: readFile(file: "${SECRET_FILE_REACT}") } } } } }
-
Running all service in parallel because if we defined it in sequence, Jenkins build will stuck on what ever run first, so this is how:
stage("Build ExpressJs and NestJs Service") { steps { parallel ( "run express" : { dir("express-service") { bat "npm install" bat "node -r dotenv/config index.js" bat "node -r dotenv/config src/configs/db.config.js" bat "node index.js" } }, "run nest": { dir("nest-service") { bat "npm install" bat "npm run start" } }, "run react": { dir("front-end-service") { bat "npm install" bat "npm run dev" } } ) } }
Final look of Jenkinsfile
This is the final look of our Jenkinsfile
.
pipeline {
agent any
environment {
SECRET_FILE_EXPRESS = credentials("customer-express-env")
SECRET_FILE_NEST = credentials("customer-nest-env")
SECRET_FILE_REACT = credentials("customer-react-env")
}
tools {
nodejs "NodeJS"
}
stages {
stage("Create ExpressJs Service ENV"){
steps{
dir("express-service") {
script {
withCredentials([file(credentialsId: "customer-express-env", variable: "SECRET_FILE_EXPRESS")]) {
writeFile file: '.env', text: readFile(file: "${SECRET_FILE_EXPRESS}")
}
}
}
}
}
stage("Create NestJs Service ENV"){
steps{
dir("nest-service") {
script {
withCredentials([file(credentialsId: "customer-nest-env", variable: "SECRET_FILE_NEST")]) {
writeFile file: '.env', text: readFile(file: "${SECRET_FILE_NEST}")
}
}
}
}
}
stage("Create React Service ENV"){
steps{
dir("front-end-service") {
script {
withCredentials([file(credentialsId: "customer-react-env", variable: "SECRET_FILE_REACT")]) {
writeFile file: '.env', text: readFile(file: "${SECRET_FILE_REACT}")
}
}
}
}
}
stage("Build ExpressJs and NestJs Service") {
steps {
parallel (
"run express" : {
dir("express-service") {
bat "npm install"
bat "node -r dotenv/config index.js"
bat "node -r dotenv/config src/configs/db.config.js"
bat "node index.js"
}
},
"run nest": {
dir("nest-service") {
bat "npm install"
bat "npm run start"
}
},
"run react": {
dir("front-end-service") {
bat "npm install"
bat "npm run dev"
}
}
)
}
}
}
}
Build Jenkins Project.
- Push the change you created in Jenkinsfile to your Git repository.
- Choose
New Item
at Jenkins Dashboard. - Enter the name for your Jenkins project. choose Pipeline. Click
OK
. - Once you got redirected to your project configuration, go to
Pipeline
section. - In Definition dropdown, choose
Pipeline script from SCM
. - In SCM dropdown, choose
Git
. - Enter your repository url. The one that you use to clone your repository. I don't set any credential since my repository is public.
- Choose the branch you want to build, mine is
main
. - I don't change anything at
Script Path
section since my Jenkinsfile name isJenkinsfile
. Please mind that it is case sensitive. - Click
Save
. - You will be redirected to your project. Choose
Build Now
. - If things are fine you will mostlikely see this:
- Since we are running our project, Jenkins will keep on going on build stage. To see if we done it right, go to your build history. Click on the latest build, which is
#1
. - Choose
Console Output
. Carefuly read the output to see if our services are running. If it does, try to go to front-end service address (still using the local address). - You will see your own interface even when you're not running it in your local because it is being run by Jenkins Server.
Posted on November 30, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 30, 2023