Bookmark this page

Lab: Building and Deploying a Full-stack Cloud-native Application

Create a multicontainer application by packaging a Helm application and by using different build strategies.

Outcomes

  • Deploy a multicontainer application on OpenShift by using various build and deploy strategies.

  • Build and publish a container image to an external registry.

  • Create Helm charts to package an OpenShift application.

  • Deploy a Node.js application from source code in a Git repository by passing build environment variables.

  • Create and consume configuration maps to store application configuration parameters.

  • Use Source-to-Image (S2I) to deploy an application.

As the student user on the workstation machine, use the lab command to prepare your environment for this exercise, and to ensure that all required resources are available.

[student@workstation ~]$ lab start compreview-todo

Specifications

  • Deploy the following components of the To Do List application to a new OpenShift project called compreview-todo:

    • A MariaDB database.

    • The todo-list API component.

    • The todo-frontend single-page application (SPA) component.

    • The todo-ssr server-side rendering (SSR) component.

      Ensure that the deployment follows Red Hat's recommendations for externalizing the configuration of applications deployed to OpenShift.

  • API requirements:

    Deploy the API and database components by creating a Helm chart.

    The chart must deploy the registry.ocp4.example.com:8443/redhattraining/todo-backend:release-46 container image from the classroom registry.

    The chart should always pull the image on a new deployment.

    The chart must deploy the MariaDB database by using version 11.3.3 of the Bitnami chart as a chart dependency. A copy of the MariaDB Bitnami chart is hosted in the classroom Helm repository at http://helm.ocp4.example.com/charts. The MariaDB Bitnami chart requires the following arguments:

    mariadb:
      auth:
        username: todouser
        password: todopwd
        database: tododb
      primary:
        podSecurityContext:
          enabled: false
        containerSecurityContext:
          enabled: false
      global:
        imageRegistry: "registry.ocp4.example.com:8443"
      image:
        tag: 10.5.10-debian-10-r0

    The environment variables required by the todo-list pod are DATABASE_USER, DATABASE_PASSWORD, DATABASE_NAME, and DATABASE_SVC.

    The service should bind to port 3000.

    Expose a public route to access the API.

  • Front end SPA requirements:

    Use the sources and Containerfile that the lab script copies to the ~/DO288/labs/compreview-todo/todo-frontend directory.

    Make no change to the HTML and TypeScript sources.

    Fix the container image by specifying the nginx user and the 8080 port.

    Build and publish the todo-frontend container image with the registry.ocp4.example.com:8443/developer/todo-frontend:latest name. Use the developer user and the developer password as the credentials for the classroom registry.

    Expose a public route to access the UI.

    Test the To Do List front end by using the exposed route.

  • Front end SSR requirements:

    Use the Source-to-Image (S2I) strategy to build and deploy the application located at the apps/compreview-todo/todo-ssr directory of the https://git.ocp4.example.com/developer/DO288-apps/ Git repository.

    Provide the todo-ssr application name to the S2I builder.

    Provide the npm_config_registry build environment variable with the http://nexus-infra.apps.ocp4.example.com/repository/npm value.

    Create and use a ConfigMap called todo-ssr-host to set the environment variable API_HOST. This variable must point to the todo-list service on port 3000, by using the HTTP protocol.

    Expose a public route to access the UI.

  • Hints:

    For the API service, the /api/items endpoint returns the current list of to do items or an empty list ([]) if no items exist.

    When the database is initializing, the API pod might fail and restart.

    If you need to uninstall your Helm chart, then you must also delete the Persistent Volume Claim (PVC) that is associated with the MariaDB database server.

    The SPA front end is working if you can create to do list items that persist when you refresh the page.

    Use the app=todo-frontend selector to delete only the UI resources.

    The SSR front end is working if you can view a page that lists the to do list items that you create with the SPA version of the front end.

    You must use the compreview-todo project to complete this exercise.

  1. Log in to Red Hat OpenShift.

    1. Log in to OpenShift as the developer user.

      [student@workstation ~]$ oc login -u developer -p developer \
      https://api.ocp4.example.com:6443
      Login successful.
      ...output omitted...
    2. Ensure that you use the compreview-todo project.

      [student@workstation ~]$ oc project compreview-todo
      Already on project "compreview-todo" on server "https://api.ocp4.example.com:6443".
  2. Create and install a Helm chart that deploys the todo-list API in the compreview-todo project. The chart must depend on the Bitnami MariaDB Helm chart. Create a route to make the component publicly available.

    1. From the lab directory, initialize a new Helm chart called todo-list and change to the directory that Helm creates.

      [student@workstation ~]$ cd ~/DO288/labs/compreview-todo
      [student@workstation compreview-todo]$ helm create todo-list
      Creating todo-list
      [student@workstation compreview-todo]$ cd todo-list
      [student@workstation todo-list]$

      Note

      The lab script provides a finished version of the Helm chart in the ~/DO288/solutions/compreview-todo/todo-list directory. You can reference this version if you are unsure of your solution.

    2. Append the following code to the contents of the Chart.yaml file, which declares the MariaDB chart as a dependency.

      dependencies:
        - name: mariadb
          version: 11.3.3
          repository: http://helm.ocp4.example.com/charts
    3. Pull the dependencies.

      [student@workstation todo-list]$ helm dependency update
      Hang tight while we grab the latest from your chart repositories...
      ...Successfully got an update from the "do288-repo" chart repository
      Update Complete. ⎈Happy Helming!⎈
      Saving 1 charts
      Downloading mariadb from repo http://helm.ocp4.example.com/charts
      Deleting outdated charts
    4. Within the values.yaml file, update the values in the image section.

      image:
        repository: registry.ocp4.example.com:8443/redhattraining/todo-backend
        pullPolicy: Always
        # Overrides the image tag whose default is the chart appVersion.
        tag: "release-46"
    5. Set the port value in the service key to 3000 in the values.yaml file.

      service:
        type: ClusterIP
        port: 3000
    6. Append the following sections to the end of the values.yaml file:

      mariadb:
        auth:
          username: todouser
          password: todopwd
          database: tododb
        primary:
          podSecurityContext:
            enabled: false
          containerSecurityContext:
            enabled: false
        global:
          imageRegistry: "registry.ocp4.example.com:8443"
        image:
          tag: 10.5.10-debian-10-r0
      
      env:
        - name: DATABASE_NAME
          value: tododb
        - name: DATABASE_USER
          value: todouser
        - name: DATABASE_PASSWORD
          value: todopwd
        - name: DATABASE_SVC
          value: todo-list-mariadb
    7. Update the templates/deployment.yaml file to add an env section within the containers section. Make sure the indentation matches up with the following content:

      apiVersion: apps/v1
      ...output omitted...
      spec:
        ...output omitted...
        template:
          ...output omitted...
          spec:
            ...output omitted...
            containers:
              - name: {{ .Chart.Name }}
                securityContext:
                  {{- toYaml .Values.securityContext | nindent 12 }}
                image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
                imagePullPolicy: {{ .Values.image.pullPolicy }}
                env:
                  {{- range .Values.env }}
                - name: {{ .name }}
                  value: {{ .value }}
                  {{- end }}
                ports:
                  - name: http
                    containerPort: {{ .Values.service.port }}
                    protocol: TCP
    8. Install the chart, providing the todo-list name:

      [student@workstation todo-list]$ helm install todo-list .
      NAME: todo-list
      LAST DEPLOYED: ...output omitted...
      NAMESPACE: compreview-todo
      STATUS: deployed
      REVISION: 1
      ...output omitted...

      This creates the resources that the Helm chart defines in the currently selected project.

    9. Verify that the application starts.

      [student@workstation todo-list]$ oc get pods
      NAME                             READY   STATUS      RESTARTS   AGE
      todo-list-7b6dbb8ccb-bqvvz       1/1     Running     2          5m57s
      todo-list-mariadb-0              1/1     Running     0          5m57s

      Note

      If your API or database pod continues to crash and restart, then you must uninstall your Helm chart, fix it, and try again. The following command uninstalls the todo-list Helm chart:

      [student@workstation todo-list]$ helm uninstall todo-list

      If the database pod is failing, then you might need to delete the data-todo-list-mariadb-0 PVC after uninstalling the todo-list Helm chart by running:

      [student@workstation todo-list]$ helm uninstall todo-list
      [student@workstation todo-list]$ oc delete pvc data-todo-list-mariadb-0
    10. Create a route to the API by using the oc expose command.

      [student@workstation todo-list]$ oc expose svc/todo-list
      route.route.openshift.io/todo-list exposed
    11. Retrieve the public URL to the service.

      [student@workstation todo-list]$ export URL_TO_APPLICATION=$(oc get \
      route/todo-list -o jsonpath='{.spec.host}')
    12. Use the URL to verify that the API is started by connecting to it.

      [student@workstation todo-list]$ curl ${URL_TO_APPLICATION}; echo
      OK
    13. Use the URL to verify that the service is connected to the database.

      [student@workstation todo-list]$ curl ${URL_TO_APPLICATION}/api/items; echo
      []
  3. Create the SPA component in OpenShift by using the oc new-app command. First you must build the container image in the todo-frontend directory and push it to the classroom registry. The container must use the nginx user and expose port 8080. Create a route to make the component publicly available.

    1. Change to the todo-frontend directory.

      [student@workstation ~]$ cd ~/DO288/labs/compreview-todo/todo-frontend
    2. Add the EXPOSE and USER commands to the Containerfile.

      COPY --from=appbuild /opt/app-root/src/build /usr/share/nginx/html
      
      EXPOSE 8080
      
      USER nginx
      
      CMD nginx -g "daemon off;"
    3. Log in with Podman to the classroom registry by using the developer account and the developer password.

      [student@workstation todo-frontend]$ podman login -u developer -p developer \
      registry.ocp4.example.com:8443
      Login Succeeded!
    4. Build the image with Podman.

      [student@workstation todo-frontend]$ podman build . \
      -t registry.ocp4.example.com:8443/developer/todo-frontend:latest
      [1/2] STEP 1/7: FROM registry.ocp4.example.com:8443/ubi8/nodejs-16 AS appbuild
      Trying to pull registry.ocp4.example.com:8443/ubi8/nodejs-14:latest...
      Getting image source signatures
      ...output omitted...
      [2/2] COMMIT registry.ocp4.example.com:8443/developer/todo-frontend:latest
      --> c3a6b1ed1bd
      Successfully tagged registry.ocp4.example.com:8443/developer/todo-frontend:latest
      c3a6b1ed1bdc36906775cc234e0368de6f95bbfec0c66c5149474a6b128abfc7

      Note

      This step is a memory-intensive task and might take several minutes to complete.

      If the build fails due to insufficient memory, then you might see the ENOMEM error. To solve the problem, close some applications and rerun the preceding command.

    5. Push the image to the classroom registry by using Podman.

      [student@workstation todo-frontend]$ podman push \
      registry.ocp4.example.com:8443/developer/todo-frontend
      Getting image source signatures
      ...output omitted...
      Writing manifest to image destination
      Storing signatures
    6. Create the todo-frontend component in OpenShift by using oc new-app.

      [student@workstation todo-frontend]$ oc new-app \
      registry.ocp4.example.com:8443/developer/todo-frontend
      --> Found container image ...output omitted...
      ...output omitted...
      --> Creating resources ...
          imagestream.image.openshift.io "todo-frontend" created
          deployment.apps "todo-frontend" created
          service "todo-frontend" created
      --> Success
      ...output omitted...
    7. Verify that the application starts.

      [student@workstation todo-frontend]$ oc get pods
      NAME                             READY   STATUS      RESTARTS   AGE
      ...output omitted...
      todo-frontend-7b4d77b4f8-lsrpm   1/1     Running     0          1m20s
    8. Create a route to the service by using the oc expose command.

      [student@workstation todo-frontend]$ oc expose svc/todo-frontend
      route.route.openshift.io/todo-frontend exposed
    9. Retrieve the public URL by examining the route.

      [student@workstation todo-frontend]$ oc get route todo-frontend \
      -o jsonpath='{.spec.host}'; echo
      todo-frontend-compreview-todo.apps.ocp4.example.com
    10. Verify that the UI works by opening the retrieved URL in a browser. The UI should contain an SPA to do list application.

    11. Verify that you can create to do list items that persist when you refresh the page.

  4. Deploy the todo-ssr application by using S2I. The source code is available in the classroom DO288-apps Git repository in the /apps/compreview-todo/todo-ssr path. The service must run on port 3000. Create a route to make the component publicly available.

    1. Use the oc new-app command with the S2I build strategy to create the todo-ssr component.

      [student@workstation todo-frontend]$ oc new-app \
      https://git.ocp4.example.com/developer/DO288-apps \
      --name todo-ssr --context-dir=/apps/compreview-todo/todo-ssr --build-env \
      npm_config_registry="http://nexus-infra.apps.ocp4.example.com/repository/npm"
      --> Found image 9350f28 (5 months old) in image stream "openshift/nodejs" under tag "12-ubi8" for "nodejs"
      ...output omitted...
      --> Creating resources ...
          imagestream.image.openshift.io "todo-ssr" created
          buildconfig.build.openshift.io "todo-ssr" created
          deployment.apps "todo-ssr" created
          service "todo-ssr" created
      --> Success
      ...output omitted...
    2. Create a ConfigMap called todo-ssr-host that contains the API_HOST environment variable.

      [student@workstation todo-frontend]$ oc create configmap todo-ssr-host \
      --from-literal API_HOST="http://todo-list:3000"
      configmap/todo-ssr-host created
    3. Inject the ConfigMap as an environment variable into the todo-ssr Deployment.

      [student@workstation todo-frontend]$ oc set env deployment/todo-ssr \
      --from cm/todo-ssr-host
      deployment.apps/todo-ssr updated

      Note that it might take a few minutes for the application to restart after attaching the ConfigMap.

    4. Verify that the application starts.

      [student@workstation todo-frontend]$ oc get pods
      NAME                             READY   STATUS      RESTARTS   AGE
      ...output omitted...
      todo-ssr-1-build             0/1     Completed   0          6m30s
      todo-ssr-64bc5f8987-7654f    1/1     Running     0          1m12s
    5. Create a route to the service by using the oc expose command.

      [student@workstation todo-frontend]$ oc expose svc/todo-ssr
      route.route.openshift.io/todo-ssr exposed
    6. Retrieve the public URL by examining the route.

      [student@workstation todo-frontend]$ oc get route todo-ssr \
      -o jsonpath='{.spec.host}'; echo
      todo-ssr-compreview-todo.apps.ocp4.example.com
    7. Verify that the static UI works by opening the retrieved URL in a browser and click To Do List. The UI should contain a static page with the to do list items that you created in the SPA version of the UI.

Evaluation

As the student user on the workstation machine, use the lab command to grade your work. Correct any reported failures and rerun the command until successful.

[student@workstation ~]$ lab grade compreview-todo

Finish

As the student user on the workstation machine, use the lab command to complete this exercise. This step is important to ensure that resources from previous exercises do not impact upcoming exercises.

[student@workstation ~]$ lab finish compreview-todo

Revision: do288-4.12-0d49506