Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Modern web applications on OpenShift, Part 4: Openshift Pipelines

April 27, 2020
Lucas Holmquist
Related topics:
CI/CDDevOpsOperators
Related products:
Red Hat OpenShift

Share:

    When I wrote part 3 of this series, Modern web applications on OpenShift: Part 3 — OpenShift as a development environment, I said that was the final part. However, there is new tech that fits in very nicely with deploying modern Web Applications to OpenShift, so part 4 is necessary. As a refresher, in the first article, we looked at how to deploy a modern web application using the fewest commands. In the second part, we took a deeper look into how the new source-to-image (S2I) web app builder works and how to use it as part of a chained build. In the third, we took a look at how to run your app's "development workflow" on Red Hat OpenShift. This article talks about OpenShift Pipelines and how this tool can be used as an alternative to a chained build.

    What is OpenShift Pipelines?

    OpenShift Pipelines are a cloud-native, continuous integration and delivery (CI/CD) solution for building pipelines using Tekton. Tekton is a flexible, Kubernetes-native, open source CI/CD framework that enables automating deployments across multiple platforms (Kubernetes, serverless, VMs, etc) by abstracting away the underlying details.

    This post assumes some knowledge of Pipelines, so if you are new to this technology, check out this official tutorial first.

    Setting up your environment

    To effectively follow this article, there is some initial setup:

    1. Set up an OpenShift 4 cluster: I've been using CodeReady Containers (CRD) to set up this environment (here are the setup instructions).
    2. Install the Pipeline Operator once your cluster is up and running, which involves only a couple of clicks (here is how to install the Operator).
    3. Get the Tekton CLI (tkn) here.
    4. Run the create-react-app CLI tool to create the application that we will eventually deploy (this basic React example).
    5. (Optional) Clone the repo to run the example locally by running npm install and then npm start.

    The application repo also has a k8s directory, which contains Kubernetes/OpenShift YAMLs that can be used to deploy the application. You can find the Tasks, ClusterTasks, Resources and Pipelines that we will be creating in this repo.

    Getting started

    We first need to create a new project on our OpenShift cluster for this example. The new project will be called webapp-pipeline. Create this new project by calling:

    $ oc new-project webapp-pipeline

    The naming here is important for this tutorial, so if you decide to change it, pay attention to where I call out that the project name, and update accordingly. From here, this article will work backward. We will create all of the small pieces that make up the pipeline first, and then we will create the pipeline.

    So, first up...

    Tasks

    Let's create a couple of tasks that can help us deploy our application later as part of our pipeline. The first task, apply_manifests_task, is responsible for applying the Kubernetes resource (service, deployment, and route) YAMLs that are in the applications k8s directory. The second task, update_deployment_task, is responsible for updating the deployed image with the new image our pipeline creates.

    Don't worry too much about these right now. These tasks are more like utilities, and we will see them in a little while. For now, create these tasks with:

    $ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/tasks/update_deployment_task.yaml
    $ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/tasks/apply_manifests_task.yaml
    

    You can then use the tkn CLI to make sure they were created:

    $ tkn task ls
    
    NAME                AGE
    apply-manifests     1 minute ago
    update-deployment   1 minute ago
    

    Note: These tasks are local to your current project.

    Cluster tasks

    A cluster task is pretty much the same thing as a task. It is still a reusable collection of steps that, when combined, perform a specific task, except that cluster task is available to the whole cluster. To see a list of the cluster tasks that came pre-installed when you added the pipeline Operator, use the tkn CLI again:

    $ tkn clustertask ls
    
    NAME                       AGE
    buildah                    1 day ago
    buildah-v0-10-0            1 day ago
    jib-maven                  1 day ago
    kn                         1 day ago
    maven                      1 day ago
    openshift-client           1 day ago
    openshift-client-v0-10-0   1 day ago
    s2i                        1 day ago
    s2i-go                     1 day ago
    s2i-go-v0-10-0             1 day ago
    s2i-java-11                1 day ago
    s2i-java-11-v0-10-0        1 day ago
    s2i-java-8                 1 day ago
    s2i-java-8-v0-10-0         1 day ago
    s2i-nodejs                 1 day ago
    s2i-nodejs-v0-10-0         1 day ago
    s2i-perl                   1 day ago
    s2i-perl-v0-10-0           1 day ago
    s2i-php                    1 day ago
    s2i-php-v0-10-0            1 day ago
    s2i-python-3               1 day ago
    s2i-python-3-v0-10-0       1 day ago
    s2i-ruby                   1 day ago
    s2i-ruby-v0-10-0           1 day ago
    s2i-v0-10-0                1 day ago
    

    We will now create two cluster tasks. The first creates an S2I image and pushes it into the internal OpenShift registry, and the second builds our NGINX-based image using the contents of our built application

    Creating and pushing the image

    For the first cluster task, we follow the part of the same process that we used in the previous article about chain builds. There, we used an S2I image (ubi8-s2i-web-app) to "build" our web application. This action resulted in an image that was stored in the internal OpenShift registry. We will use that web-app S2I image to create a DockerFile for our application and then use Buildah to actually build and push that image into the internal OpenShift registry: This is actually what OpenShift does if you deploy your applications with NodeShift.

    If you're wondering how I knew that I needed all of those steps, the answer is that I didn't. I copied the official Node.js version and updated it for my needs.

    Now, create the s2i-web-app cluster task:

    $ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/s2i-web-app-task.yaml
    

    I won't go into each of the entries in that file but I do want to point out a particular parameter: OUTPUT_DIR:

    params:
          - name: OUTPUT_DIR
            description: The location of the build output directory
            default: build
    

    This parameter defaults to build, which is where React puts its built content. Different frameworks could have different locations. For example, Ember uses dist. The output of this first cluster task will be an image that contains our built HTML, JavaScript, and CSS.

    Build the NGINX-based image

    For the second cluster task, we need to create the task that builds our NGINX-based image using the contents of our built application. This is basically the chained build part of the aforementioned article.

    To do this, create the webapp-build-runtime cluster task the same as with the other one:

    $ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/webapp-build-runtime-task.yaml
    

    If you looked at the code for these cluster tasks, you would notice that we are not specifying what Git repo we are working with, or what image names we are creating. We only specify that we are passing in a Git repo or an image, for example, and that we are outputting an image. This process allows us to reuse these cluster tasks with different applications.

    This leads us nicely into...

    Resources

    Since we just learned that our cluster tasks are meant to be generic as possible, we need to create resources to use as inputs (the Git repo) and outputs (the resulting images). The first resource we need is the Git repo where our application is. This resource can look something like this:

    # This resource is the location of the git repo with the web application source
    apiVersion: tekton.dev/v1alpha1
    kind: PipelineResource
    metadata:
      name: web-application-repo
    spec:
      type: git
      params:
        - name: url
          value: https://github.com/nodeshift-starters/react-pipeline-example
        - name: revision
          value: master
    

    This PipelineResource is of the git type. We can see in the params section that the url targets a specific repo and that we also specify the master branch (this is optional, but I'm including it for completeness).

    The next resource we need is an image where we will store the result of the s2i-web-app task. This process might look something like:

    # This resource is the result of running "npm run build",  the resulting built files will be located in /opt/app-root/output
    apiVersion: tekton.dev/v1alpha1
    kind: PipelineResource
    metadata:
      name: built-web-application-image
    spec:
      type: image
      params:
        - name: url
          value: image-registry.openshift-image-registry.svc:5000/webapp-pipeline/built-web-application:latest
    

    This PipelineResource is of the image type and the value of url points to the internal OpenShift Image Registry—specifically the one in the webapp-pipeline namespace. If you are using a different namespace, then change that value accordingly.

    The last resource will also be an image type, and this will be the resulting NGINX image that we will eventually deploy:

    # This resource is the image that will be just the static html, css, js files being run with nginx
    apiVersion: tekton.dev/v1alpha1
    kind: PipelineResource
    metadata:
      name: runtime-web-application-image
    spec:
      type: image
      params:
        - name: url
          value: image-registry.openshift-image-registry.svc:5000/webapp-pipeline/runtime-web-application:latest
    

    Again, this resource will store the image inside the internal OpenShift registry in the webapp-pipeline namespace.

    To create all of these resources at once, run this create command:

    $ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/resources/resource.yaml
    

    You can then see the created resources using:

    $ tkn resource ls
    

    The pipeline

    Now that we have all of the pieces, let's put them together in our pipeline. You can create the pipeline by running the following command:

    $ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/pipelines/build-and-deploy-react.yaml
    

    Before we run this command, let's take a look at the pieces. First, the name:

    apiVersion: tekton.dev/v1alpha1
    kind: Pipeline
    metadata:
      name: build-and-deploy-react
    

    Then, in the spec section, we see specify the resources that we created earlier:

    spec:
      resources:
        - name: web-application-repo
          type: git
        - name: built-web-application-image
          type: image
        - name: runtime-web-application-image
          type: image
    

    We then create tasks for our pipeline to run. The first task we want to run is the s2i-web-app cluster task we created earlier:

    tasks:
        - name: build-web-application
          taskRef:
            name: s2i-web-app
            kind: ClusterTask
    

    This task takes an input (which is the git resource) and an output (which is the built-web-application-image resource). We also pass a parameter to tell our cluster task that we don't need to verify TLS because we are using self-signed certificates:

    resources:
            inputs:
              - name: source
                resource: web-application-repo
            outputs:
              - name: image
                resource: built-web-application-image
          params:
            - name: TLSVERIFY
              value: "false"
    

    The next task has a similar setup, but this time calls the webapp-build-runtime cluster task we created earlier:

    name: build-runtime-image
        taskRef:
          name: webapp-build-runtime
          kind: ClusterTask
    

    Similar to our previous task, we are passing a resource, but this time it is the built-web-application-image (this was the output of our previous task). Again, we specify an image as the output. This task should run after the previous task, so we add the runAfter field:

    resources:
            inputs:
              - name: image
                resource: built-web-application-image
            outputs:
              - name: image
                resource: runtime-web-application-image
            params:
            - name: TLSVERIFY
              value: "false"
          runAfter:
            - build-web-application
    

    The next two tasks are responsible for applying the service, route, and deployment YAML files that live in the web application's k8s directory, and then updating the deployment with the newly created image. These are the two cluster tasks we defined in the beginning.

    Run the pipeline

    Now that all of the pieces are created, we can finally run our new pipeline with the following command:

    $ tkn pipeline start build-and-deploy-react
    

    At this point, the CLI will become interactive, and you will need to choose the appropriate resources at each prompt. For the git resource, choose web-application-repo. Then, choose built-web-application-image for the first image resource and runtime-web-application-image for the second image resource:

    ? Choose the git resource to use for web-application-repo: web-application-repo (https://github.com/nodeshift-starters/react-pipeline-example)
    ? Choose the image resource to use for built-web-application-image: built-web-application-image (image-registry.openshift-image-registry.svc:5000/webapp-pipeline/built-web-
    application:latest)
    ? Choose the image resource to use for runtime-web-application-image: runtime-web-application-image (image-registry.openshift-image-registry.svc:5000/webapp-pipeline/runtim
    e-web-application:latest)
    Pipelinerun started: build-and-deploy-react-run-4xwsr
    

    Check the status of the pipeline by running:

    $ tkn pipeline logs -f
    

    After the pipeline has finished and the application is deployed, get the exposed route with this little command:

    $ oc get route react-pipeline-example --template='http://{{.spec.host}}'
    

    For a more visual approach, we can look at our pipeline in the web console's Developer view and click the Pipelines section, as shown in Figure 1.

    Pipeline overview
    Overview of a Running Pipeline

    Figure 1: Overview of a running pipeline.">

    Click the running pipeline to see more detail, as shown in Figure 2.

    Pipeline detail
    Running Pipeline Detail

    Figure 2: The running pipeline's details.">

    Once you have the details, you can see your running application in the Topology view, as shown in Figure 3.

    Web App Topology View
    Running Pod

    Figure 3: The running pod.">

    Clicking the icon on the circle's top right opens the application. Figure 4 shows what this will look like.

    Running React Application
    React Application

    Figure 4: Running the React application.">

    Wrapping up

    In this article, we saw how to mimic the chained-build template approach with the use of OpenShift Pipelines. You can find all of the things we created in this repo. There are also some GitHub issues there for adding an example with another framework besides React, so feel free to contribute!

    Last updated: February 5, 2024

    Recent Posts

    • Assessing AI for OpenShift operations: Advanced configurations

    • OpenShift Lightspeed: Assessing AI for OpenShift operations

    • OpenShift Data Foundation and HashiCorp Vault securing data

    • Axolotl meets LLM Compressor: Fast, sparse, open

    • What’s new for developers in Red Hat OpenShift 4.19

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue