In my previous blog, I wrote how to install Red Hat Openshift local on a personal laptop. Now, it’s time to step ahead and explore the local Openshift cluster. So, I thought to start with an elementary step. In this simple step-by-step tutorial, I’ll demonstrate how to deploy a Node.js app in Red Hat Openshift. There are many ways of doing it. I’ll use the source-to-image (S2I) feature of Red Hat Openshift in this article.
What is source-to-image (S2I) from Red hat OpenShift?
Let’s check directly from Openshift documentation:
Source-to-Image (S2I) is a framework that makes it easy to write images that take application source code as an input and produce a new image that runs the assembled application as output.
https://docs.openshift.com/container-platform/3.11/creating_images/s2i.html
Basically. S2I framework allows us to create Docker container images from the source code without writing a single line of code. The following image from Red Hat explains the concepts beautifully.

It’s worth noting that the S2I utility is a separate open-source module that we can use even outside Red Hat OpenShift. It’s available on Github: https://github.com/openshift/source-to-image.
In this article, I will use the source-to-image (S2I) feature to deploy a Node.js app in the Red Hat Openshift local cluster.
Prerequisite
- You must have access to an up-and-running Red Hat Openshift cluster. Here, I’ll use my locally installed cluster.
Build Node.js application
Sometimes back, I wrote a blog on how to deploy a Node.js application in a vanilla Kubernetes cluster. I’ll use the same Node.js app to deploy in Openshift. Hence, I won’t lengthen the article by repeating the same steps. You can go through the steps mentioned in the Build Node.js application section.
For better maintenance, I have cloned the code & other fields to a new repo, which is available in the https://github.com/msadrud/openshift-nodejs-hello-world repository.
Deploy the Node.js app
The time needed: 20 minutes.
- Start the Red Hat Openshift Cluster.
I am using a locally installed Red Hat Openshift cluster. So, I’ll manually start the cluster. You can skip this step if you are using an already running cluster. Ensure that the oc command line utility is set up.
NOTE: Refer here if you are not sure how to start your local cluster or setup oc command line utility.
- Create a new project using the oc command
Now, we’ll use the oc command to create a new project in the Openshift cluster. Issue the following command.
$ oc login -u developer -p developer https://api.crc.testing:6443
Login successful.
$ oc new-project mynodeproject
Now using project "mynodeproject" on server "https://api.crc.testing:6443".
At this point, if we open the Openshift web console and click on the Topology, we won’t see any resource. A page similar to the following snippet will be visible.

We can deploy the node.js app using either the GUI or the command line. We’ll do both, but first, let’s try the GUI.
GUI-based steps to deploy a Node.js app in Red Hat Openshift using source-to-image (S2I) :
- Click on the +Add menu item from the left pen and then select the Import from Git option on the page that opens on the right.

- Provide the Git repository URL. It’ll validate the repository artifacts and show you some options below with auto-populated values. You can always go through each of those and change them to suit your need. However, in this POC, we’ll keep everything default. Ensure you have not unchecked the Create a route to the Application option; it should remain checked as it is by default. Click on Create button.

- After a while, you will notice that the Topology window is now populated with one Deployment resource. Our pod is now running!!

- Click on the little Open URL icon towards the top-right corner(red-marked in the snippet), and a new tab in your web browser will open up with the response from the Node.js app we created.

- Hurray!! We just ran our Node.js app 🙂

Let’s check the different objects that OpenShift S2I process created in this process:
$ oc get all
NAME READY STATUS RESTARTS AGE
pod/openshift-nodejs-hello-world-1-build 0/1 Completed 0 34d
pod/openshift-nodejs-hello-world-dc869f4f7-rbr7z 1/1 Running 6 34d
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/openshift-nodejs-hello-world ClusterIP 10.217.4.204 <none> 8080/TCP 34d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/openshift-nodejs-hello-world 1/1 1 1 34d
NAME DESIRED CURRENT READY AGE
replicaset.apps/openshift-nodejs-hello-world-68db9b8974 0 0 0 34d
replicaset.apps/openshift-nodejs-hello-world-dc869f4f7 1 1 1 34d
NAME TYPE FROM LATEST
buildconfig.build.openshift.io/openshift-nodejs-hello-world Source Git 1
NAME TYPE FROM STATUS STARTED DURATION
build.build.openshift.io/openshift-nodejs-hello-world-1 Source Git@696687c Complete 4 weeks ago 52s
NAME IMAGE REPOSITORY TAGS UPDATED
imagestream.image.openshift.io/openshift-nodejs-hello-world default-route-openshift-image-registry.apps-crc.testing/mynodeproject/openshift-nodejs-hello-world latest 4 weeks ago
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
route.route.openshift.io/openshift-nodejs-hello-world openshift-nodejs-hello-world-mynodeproject.apps-crc.testing openshift-nodejs-hello-world 8080-tcp edge/Redirect None
Tip
The result of oc get pods command is interesting. It shows two pods. One of them is in running state which is our actual application pod. But, there is also another pod, with -build suffix, in completed state. What is the significance this other pod?
Well, the build process took the source code of our node.js application and combined it with the builder image to create a custom image of the application. This process used the build pod to create this custom container image.
CLI-based steps to deploy a Node.js app in Red Hat Openshift using source-to-image (S2I) :
Another simple way to deploy the app is to use the powerful oc command line utility. To distinguish this POC from GUI based method, I have updated the index.js file with a new message, “Hello World from k8s cli-build!”. Now, let’s proceed:
- Let’s create a new project mynodecliproject
$ oc new-project mynodecliproject --display-name='OpenShift Project to showcase the S2I build using CLIs'
Now using project "mynodecliproject" on server "https://api.crc.testing:6443".
You can add applications to this project with the 'new-app' command. For example, try:
oc new-app rails-postgresql-example
to build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application:
kubectl create deployment hello-node --image=k8s.gcr.io/e2e-test-images/agnhost:2.33 -- /agnhost serve-hostname
- Create the new application openshift-nodejs-hello-world-cli
$ oc new-app --code=https://github.com/msadrud/openshift-nodejs-hello-world.git --name=openshift-nodejs-hello-world-cli
--> Found image 1812c39 (3 months old) in image stream "openshift/nodejs" under tag "16-ubi8" for "nodejs"
Node.js 16
----------
Node.js 16 available as container is a base platform for building and running various Node.js 16 applications and frameworks. Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
Tags: builder, nodejs, nodejs16
* The source repository appears to match: nodejs
* A source build using source code from https://github.com/msadrud/openshift-nodejs-hello-world.git will be created
* The resulting image will be pushed to image stream tag "openshift-nodejs-hello-world-cli:latest"
* Use 'oc start-build' to trigger a new build
--> Creating resources ...
imagestream.image.openshift.io "openshift-nodejs-hello-world-cli" created
buildconfig.build.openshift.io "openshift-nodejs-hello-world-cli" created
deployment.apps "openshift-nodejs-hello-world-cli" created
service "openshift-nodejs-hello-world-cli" created
--> Success
Build scheduled, use 'oc logs -f buildconfig/openshift-nodejs-hello-world-cli' to track its progress.
Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
'oc expose service/openshift-nodejs-hello-world-cli'
Run 'oc status' to view your app.
- Unlike the GUI method, OpenShift does not create route objects. We’ll need to expose the service object using the following command:
$ oc expose svc/openshift-nodejs-hello-world-cli
route.route.openshift.io/openshift-nodejs-hello-world-cli exposed
- Now, let’s describe the route and figure out the URL of the application from the Requested Host field below:
$ oc describe route/openshift-nodejs-hello-world-cli
Name: openshift-nodejs-hello-world-cli
Namespace: mynodecliproject
Created: 3 minutes ago
Labels: app=openshift-nodejs-hello-world-cli
app.kubernetes.io/component=openshift-nodejs-hello-world-cli
app.kubernetes.io/instance=openshift-nodejs-hello-world-cli
Annotations: openshift.io/host.generated=true
Requested Host: openshift-nodejs-hello-world-cli-mynodecliproject.apps-crc.testing
exposed on router default (host router-default.apps-crc.testing) 3 minutes ago
Path: <none>
TLS Termination: <none>
Insecure Policy: <none>
Endpoint Port: 8080-tcp
Service: openshift-nodejs-hello-world-cli
Weight: 100 (100%)
Endpoints: 10.217.0.57:8080
- Copy the value of the host and test it from the browser. It’ll render the response from our node.js application.

What are the components created by the S2I build process?
Now, a bit of theory. Let’s look at the components created by the above S2I build process. Applications in OpenShift don’t get deployed in a monolithic way. It consists of several different components that work together to maintain the application lifecycle. PFB a list of the important components:
- Image
- Image Streams
- Pods
- Build
- BuildConfig
- Deployment
- Services
- Routes
In OpenShift For Developers book, the distinguished authors very nicely described the application components that OpenShift creates and, amongst them, which components are of native Kubernetes and which are of OpenShift. Let’s take a look.

Image
When OpenShift deploys an application using the S2I framework, it creates an image of the application using its source code and a builder image. An S2I builder image is a basic container image supporting a language created following the S2I specification. There are many S2I builder images for different languages, for example, .Net, Java, Node.js, Perl, etc. In this tutorial, we are using a Node.js builder image. However, as we are using the wizard of OpenShift itself, we don’t have to choose the builder image ourselves; instead, OpenShift will take care of it automatically.
ImageStream
One crucial point to understand about ImageStream is that it does not contain the actual image. The actual image is stored in either the in-built image registry of the OCP platform or an external image registry. We can consider ImageStream as an abstraction layer on top of the actual image registry.
When an object configuration (E.g., Build or Deployment) wants to refer to an image, it points to the image stream and not to the image registry directly. In execution time, OCP queries the actual registry behind ImageStream to locate and use the actual image.
$ oc describe imagestream/openshift-nodejs-hello-world
Name: openshift-nodejs-hello-world
Namespace: mynodeproject
Created: 4 weeks ago
Labels: app=openshift-nodejs-hello-world
app.kubernetes.io/component=openshift-nodejs-hello-world
app.kubernetes.io/instance=openshift-nodejs-hello-world
app.kubernetes.io/name=openshift-nodejs-hello-world
app.kubernetes.io/part-of=openshift-nodejs-hello-world-app
app.openshift.io/runtime=nodejs
app.openshift.io/runtime-version=16-ubi8
Annotations: app.openshift.io/vcs-ref=
app.openshift.io/vcs-uri=https://github.com/msadrud/openshift-nodejs-hello-world
openshift.io/generated-by=OpenShiftWebConsole
Image Repository: default-route-openshift-image-registry.apps-crc.testing/mynodeproject/openshift-nodejs-hello-world
Image Lookup: local=false
Unique Images: 1
Tags: 1
latest
no spec tag
* image-registry.openshift-image-registry.svc:5000/mynodeproject/openshift-nodejs-hello-world@sha256:837cfc4fe65b2a69dd17da29379bdee8f801d23fa52dc3d5f4e5b5d283448216
4 weeks ago
Pod
Pods are the smallest deployable units of computing that one can create and manage in Kubernetes. A pod generally contains one container. However, having more than one container in a single pod is possible. The container(s) inside the pod share storage and network resources. Pods are ephemeral. However, pods can be configured to run the stateful applications as well.
Build
Generally, Build is a process that takes specific inputs and creates the desired artifact. In the OCP context, the Build process takes the source code and builder image to create the custom application image. The instruction for the build process is stored as BuildConfig.
The image building process starts a container from the builder image, downloads and integrates the application source into the builder image container, runs the assemble script from the builder image, and saves the final custom container image for the provided application into the image registry.
$ oc get builds
NAME TYPE FROM STATUS STARTED DURATION
openshift-nodejs-hello-world-1 Source Git@696687c Complete 4 weeks ago 52s
$ oc describe builds/openshift-nodejs-hello-world-1
Name: openshift-nodejs-hello-world-1
Namespace: mynodeproject
Created: 4 weeks ago
Labels: app=openshift-nodejs-hello-world
app.kubernetes.io/component=openshift-nodejs-hello-world
app.kubernetes.io/instance=openshift-nodejs-hello-world
app.kubernetes.io/name=openshift-nodejs-hello-world
app.kubernetes.io/part-of=openshift-nodejs-hello-world-app
app.openshift.io/runtime=nodejs
app.openshift.io/runtime-version=16-ubi8
buildconfig=openshift-nodejs-hello-world
openshift.io/build-config.name=openshift-nodejs-hello-world
openshift.io/build.start-policy=Serial
Annotations: openshift.io/build-config.name=openshift-nodejs-hello-world
openshift.io/build.number=1
openshift.io/build.pod-name=openshift-nodejs-hello-world-1-build
Status: Complete
Started: Tue, 26 Jul 2022 23:49:35 +03
Duration: 52s
FetchInputs: 2s
PullImages: 25s
Build: 9s
PushImage: 0s
Build Config: openshift-nodejs-hello-world
Build Pod: openshift-nodejs-hello-world-1-build
Image Digest: sha256:837cfc4fe65b2a69dd17da29379bdee8f801d23fa52dc3d5f4e5b5d283448216
Strategy: Source
URL: https://github.com/msadrud/openshift-nodejs-hello-world
ContextDir: /
Commit: 696687c (Update package.json)
Author/Committer: Sadruddin Mohammed / GitHub
From Image: DockerImage image-registry.openshift-image-registry.svc:5000/openshift/nodejs@sha256:e5d9ddf7fd85e10276991e39c3249321593469524f408425b7828f421c7ce77d
Pull Secret Name: builder-dockercfg-p2mgc
Volumes: <none>
Output to: ImageStreamTag openshift-nodejs-hello-world:latest
Push Secret: builder-dockercfg-p2mgc
Build trigger cause: Build configuration change
Events: <none>
BuildConfig
The BuildConfig is an OpenShift custom resource that defines a single build definition. It contains all the information needed to build an application image from a specified source; for example, how the Build is triggered, build strategies (Docker, Source, Custom, Pipeline), the name of the builder image, the name of the resultant image, where to store that image, etc. A BuildConfig is automatically created as part of the build process when using the S2I build process.
$ oc describe buildconfig/openshift-nodejs-hello-world
Name: openshift-nodejs-hello-world
Namespace: mynodeproject
Created: 4 weeks ago
Labels: app=openshift-nodejs-hello-world
app.kubernetes.io/component=openshift-nodejs-hello-world
app.kubernetes.io/instance=openshift-nodejs-hello-world
app.kubernetes.io/name=openshift-nodejs-hello-world
app.kubernetes.io/part-of=openshift-nodejs-hello-world-app
app.openshift.io/runtime=nodejs
app.openshift.io/runtime-version=16-ubi8
Annotations: app.openshift.io/vcs-ref=
app.openshift.io/vcs-uri=https://github.com/msadrud/openshift-nodejs-hello-world
openshift.io/generated-by=OpenShiftWebConsole
Latest Version: 1
Strategy: Source
URL: https://github.com/msadrud/openshift-nodejs-hello-world
ContextDir: /
From Image: ImageStreamTag openshift/nodejs:16-ubi8
Volumes: <none>
Output to: ImageStreamTag openshift-nodejs-hello-world:latest
Build Run Policy: Serial
Triggered by: ImageChange, Config
Webhook Generic:
URL: https://api.crc.testing:6443/apis/build.openshift.io/v1/namespaces/mynodeproject/buildconfigs/openshift-nodejs-hello-world/webhooks/<secret>/generic
AllowEnv: false
Webhook GitHub:
URL: https://api.crc.testing:6443/apis/build.openshift.io/v1/namespaces/mynodeproject/buildconfigs/openshift-nodejs-hello-world/webhooks/<secret>/github
Builds History Limit:
Successful: 5
Failed: 5
Build Status Duration Creation Time
openshift-nodejs-hello-world-1 complete 52s 2022-07-26 23:49:34 +0300 +03
Events: <none>
Deployment
As described clearly in the OCP documentation, the Deployment object describes the desired state of a particular application component as a pod template. A deployment is an object in OCP, and it is enabled by a native K8S API object called ReplicaSet. ReplicaSet in K8S ensures the configured number of pod replicas are running at any time. Simply put, Deployments in OpenShift create replica sets that, in turn, orchestrate the pod life cycle.
$ oc describe deployment/openshift-nodejs-hello-world
Name: openshift-nodejs-hello-world
Namespace: mynodeproject
CreationTimestamp: Tue, 26 Jul 2022 23:49:34 +0300
Labels: app=openshift-nodejs-hello-world
app.kubernetes.io/component=openshift-nodejs-hello-world
app.kubernetes.io/instance=openshift-nodejs-hello-world
app.kubernetes.io/name=openshift-nodejs-hello-world
app.kubernetes.io/part-of=openshift-nodejs-hello-world-app
app.openshift.io/runtime=nodejs
app.openshift.io/runtime-version=16-ubi8
Annotations: alpha.image.policy.openshift.io/resolve-names: *
app.openshift.io/route-disabled: false
app.openshift.io/vcs-ref:
app.openshift.io/vcs-uri: https://github.com/msadrud/openshift-nodejs-hello-world
deployment.kubernetes.io/revision: 2
image.openshift.io/triggers:
[{"from":{"kind":"ImageStreamTag","name":"openshift-nodejs-hello-world:latest","namespace":"mynodeproject"},"fieldPath":"spec.template.spe...
openshift.io/generated-by: OpenShiftWebConsole
Selector: app=openshift-nodejs-hello-world
Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=openshift-nodejs-hello-world
deploymentconfig=openshift-nodejs-hello-world
Containers:
openshift-nodejs-hello-world:
Image: image-registry.openshift-image-registry.svc:5000/mynodeproject/openshift-nodejs-hello-world@sha256:837cfc4fe65b2a69dd17da29379bdee8f801d23fa52dc3d5f4e5b5d283448216
Port: 8080/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Progressing True NewReplicaSetAvailable
Available True MinimumReplicasAvailable
OldReplicaSets: <none>
NewReplicaSet: openshift-nodejs-hello-world-dc869f4f7 (1/1 replicas created)
Events: <none>
Service
Service works as an internal load balancer/Proxy that receives the traffic and sends it to one or more pods behind. We can add or remove pods as required without impacting the service. Service distributes the traffic to its associated and available pods seamlessly. By default, OpenShift assigns a cluster internal IP to the service, which is not accessible from outside the cluster.
$ oc describe svc/openshift-nodejs-hello-world
Name: openshift-nodejs-hello-world
Namespace: mynodeproject
Labels: app=openshift-nodejs-hello-world
app.kubernetes.io/component=openshift-nodejs-hello-world
app.kubernetes.io/instance=openshift-nodejs-hello-world
app.kubernetes.io/name=openshift-nodejs-hello-world
app.kubernetes.io/part-of=openshift-nodejs-hello-world-app
app.openshift.io/runtime=nodejs
app.openshift.io/runtime-version=16-ubi8
Annotations: app.openshift.io/vcs-ref:
app.openshift.io/vcs-uri: https://github.com/msadrud/openshift-nodejs-hello-world
openshift.io/generated-by: OpenShiftWebConsole
Selector: app=openshift-nodejs-hello-world,deploymentconfig=openshift-nodejs-hello-world
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.217.4.204
IPs: 10.217.4.204
Port: 8080-tcp 8080/TCP
TargetPort: 8080/TCP
Endpoints: 10.217.0.23:8080
Session Affinity: None
Events: <none>
Route
As we just learned, a service is visible only inside the cluster. So, we can consume the application through the service layer only from inside the cluster. A route exposes a service to the external world using HTTP or HTTPS based on our preference. The Route is accessible in the outer world because a public DNS entry is created.
$ oc describe route/openshift-nodejs-hello-world
Name: openshift-nodejs-hello-world
Namespace: mynodeproject
Created: 4 weeks ago
Labels: app=openshift-nodejs-hello-world
app.kubernetes.io/component=openshift-nodejs-hello-world
app.kubernetes.io/instance=openshift-nodejs-hello-world
app.kubernetes.io/name=openshift-nodejs-hello-world
app.kubernetes.io/part-of=openshift-nodejs-hello-world-app
app.openshift.io/runtime=nodejs
app.openshift.io/runtime-version=16-ubi8
Annotations: openshift.io/host.generated=true
Requested Host: openshift-nodejs-hello-world-mynodeproject.apps-crc.testing
exposed on router default (host router-default.apps-crc.testing) 4 weeks ago
Path: <none>
TLS Termination: edge
Insecure Policy: Redirect
Endpoint Port: 8080-tcp
Service: openshift-nodejs-hello-world
Weight: 100 (100%)
Endpoints: 10.217.0.23:8080
Deploy a new change/update in the existing source code
Thus far, we built an image using S2I and then deployed that in OpenShift. Now, let’s see how we can deploy any change in the source code.
We’ll explore both GUI-based and CLI-based approaches
Redeploy the updated code using GUI
We’ll update the code in the index.js file in the git repository. We’ll update the existing response string to “Hello World from OpenShift!” in line number 6.
Let’s return to the OpneShift web console and traverse to Builds->BuildConfigs. We’ll click on the triple vertical dot on the right and then click on the Start build menu item [Refer to the picture below]

The build process will start; give it a while to complete the process. After that, switch to Developer mode, and click on the Topology menu item. You’ll notice that the Topology window is now populated with an updated Deployment resource. Our new pod is now running!!

Click on the little arrow icon with the tooltip “Open URL.”; it’ll open a new browser tab and display the updated message.

Now, by executing the oc get all commands, let’s see what the resources/objects newly created in our cluster are:
- We can see that the OpenShift created a new build pod.
- The old application pod is no more there; instead, we have a new pod that runs the updated code.
- OpenShift created a new replica set for the new deployment that we did.
- There is a new build as well.
- The image stream is pointing to the latest version of the image.
$ oc get all
NAME READY STATUS RESTARTS AGE
pod/openshift-nodejs-hello-world-1-build 0/1 Completed 0 35d
pod/openshift-nodejs-hello-world-2-build 0/1 Completed 0 11m
pod/openshift-nodejs-hello-world-7b586db5b4-h9k4p 1/1 Running 0 10m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/openshift-nodejs-hello-world ClusterIP 10.217.4.204 <none> 8080/TCP 35d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/openshift-nodejs-hello-world 1/1 1 1 35d
NAME DESIRED CURRENT READY AGE
replicaset.apps/openshift-nodejs-hello-world-68db9b8974 0 0 0 35d
replicaset.apps/openshift-nodejs-hello-world-7b586db5b4 1 1 1 10m
replicaset.apps/openshift-nodejs-hello-world-dc869f4f7 0 0 0 35d
NAME TYPE FROM LATEST
buildconfig.build.openshift.io/openshift-nodejs-hello-world Source Git 2
NAME TYPE FROM STATUS STARTED DURATION
build.build.openshift.io/openshift-nodejs-hello-world-1 Source Git@696687c Complete 5 weeks ago 52s
build.build.openshift.io/openshift-nodejs-hello-world-2 Source Git@1eb9b11 Complete 11 minutes ago 51s
NAME IMAGE REPOSITORY TAGS UPDATED
imagestream.image.openshift.io/openshift-nodejs-hello-world default-route-openshift-image-registry.apps-crc.testing/mynodeproject/openshift-nodejs-hello-world latest 10 minutes ago
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
route.route.openshift.io/openshift-nodejs-hello-world openshift-nodejs-hello-world-mynodeproject.apps-crc.testing openshift-nodejs-hello-world 8080-tcp edge/Redirect None
Redeploy the updated code using CLI
To distinguish our POC from the GUI-based method, let’s update the code in the index.js file in the git repository. We’ll update the existing response string to “Hello World from OpenShift cli-build!” in line number 6. We’ll execute the following command:
$ oc start-build bc/openshift-nodejs-hello-world-cli
build.build.openshift.io/openshift-nodejs-hello-world-cli-2 started
Now, let’s refresh the browser and see the result:

Conclusion
Through this article, I wanted to document my learning and observations (for future reference) and share the same with you.
In my learning process, I went through many articles on the internet and also scanned through books. I have listed those below, and I hope I didn’t miss any!