Find the Best Cosmetic Hospitals

Explore trusted cosmetic hospitals and make a confident choice for your transformation.

โ€œInvest in yourself โ€” your confidence is always worth it.โ€

Explore Cosmetic Hospitals

Start your journey today โ€” compare options in one place.

OpenShift Lab 13: Deploy a Java Spring Boot Application with MySQL Using the OpenShift Web Console

Lab Objective

In this lab, you will deploy a Java Spring Boot application on OpenShift using the OpenShift web console.

You will deploy two components:

  1. A MySQL database.
  2. A Java Spring PetClinic application.

The Java application will connect to the MySQL database using OpenShift internal service discovery.

This lab is a modern replacement for the older โ€œDeploy a Java application on Kubernetesโ€ lab. The original lab used Developer Sandbox and an ephemeral MySQL template. This replacement is updated for OpenShift Local and uses current OpenShift resources such as Deployment, Service, Secret, PersistentVolumeClaim, BuildConfig, ImageStream, and Route.


What You Will Learn

You will learn how to:

  1. Start OpenShift Local.
  2. Log in to the OpenShift web console.
  3. Create a new OpenShift project.
  4. Deploy MySQL using the web console.
  5. Store database credentials in a Secret.
  6. Store MySQL data on a PersistentVolumeClaim.
  7. Expose MySQL internally using a Service.
  8. Import a Java Spring Boot application from Git.
  9. Build the Java application using OpenShift Source-to-Image.
  10. Use the Java builder image.
  11. Configure the Java application to connect to MySQL.
  12. Deploy the application using a Kubernetes Deployment.
  13. Expose the Java application externally using a Route.
  14. Validate the application from the browser.
  15. Validate database connectivity from CLI.
  16. Troubleshoot common build, deployment, and database issues.
  17. Clean up the lab environment.

Lab Architecture

GitHub Repository
     |
     v
OpenShift Source-to-Image Build
     |
     v
Application Image
     |
     v
Spring PetClinic Deployment
     |
     v
Spring PetClinic Pod
     |
     v
Spring PetClinic Service
     |
     v
Spring PetClinic Route
     |
     v
Browser


Spring PetClinic Pod
     |
     | jdbc:mysql://mysql:3306/petclinic
     v
MySQL Service
     |
     v
MySQL Pod
     |
     v
PersistentVolumeClaim
Code language: JavaScript (javascript)

Resources Created in This Lab

ResourceNamePurpose
Projectlab13-java-mysqlIsolated namespace for the lab
Secretmysql-secretStores MySQL credentials
PersistentVolumeClaimmysql-dataStores MySQL data
DeploymentmysqlRuns the MySQL database
ServicemysqlProvides internal DNS name for MySQL
BuildConfigspring-petclinicDefines how OpenShift builds the Java app
Buildspring-petclinic-1One execution of the app build
ImageStreamspring-petclinicTracks the built app image
Deploymentspring-petclinicRuns the Java app
Servicespring-petclinicProvides internal access to the Java app
Routespring-petclinicProvides browser access to the Java app

Important Concept: Kubernetes vs OpenShift

The original article title says Kubernetes, but this lab uses OpenShift features.

Plain Kubernetes does not provide these OpenShift-specific features by default:

Source-to-Image
BuildConfig
ImageStream
Route
Developer perspective
OpenShift web console import flow
Code language: JavaScript (javascript)

So the technically correct title for this lab is:

Deploy a Java Spring Boot Application with MySQL on OpenShift
Code language: JavaScript (javascript)

OpenShift runs Kubernetes underneath, but this lab specifically teaches the OpenShift developer workflow.


Important Concept: Why MySQL Is Not Exposed with a Route

A MySQL database should normally not be exposed publicly.

The Java application connects to MySQL internally using:

mysql:3306
Code language: CSS (css)

This works because mysql is the name of the OpenShift Service.

The Java application will use this JDBC URL:

jdbc:mysql://mysql:3306/petclinic
Code language: JavaScript (javascript)

The Java app gets an external Route because it is a web application.

The MySQL database does not get a Route because it is an internal database service.


Important Concept: Why We Use Deployment Instead of DeploymentConfig

Older OpenShift labs often used DeploymentConfig.

This lab uses:

Deployment

Deployment is the standard Kubernetes workload resource and is the preferred resource type for modern beginner labs.

When the web console asks for the resource type, select:

Deployment

Do not select:

DeploymentConfig

Part 1: Prerequisites

Required Tools

You need:

  1. OpenShift Local installed.
  2. The crc command available.
  3. The oc command available.
  4. Browser access to the OpenShift web console.
  5. Internet access from OpenShift Local to GitHub and container registries.
  6. A valid Red Hat pull secret configured for OpenShift Local.

Recommended Local Machine Resources

For this lab, use at least:

ResourceRecommended
CPU4 cores or more
Memory12 GB or more
Disk35 GB or more

Java builds can be slow on small laptops. More memory will make this lab smoother.


Part 2: Start OpenShift Local

Open a terminal.

Check the CRC version:

crc version

Set the OpenShift preset:

crc config set preset openshift
Code language: JavaScript (javascript)

Run setup:

crc setup

Start OpenShift Local:

crc start

The cluster may take several minutes to start.

After the cluster starts, view the login credentials:

crc console --credentials
Code language: JavaScript (javascript)

Open the web console:

crc console
Code language: JavaScript (javascript)

Part 3: Configure the oc CLI

Run:

crc oc-env

On Linux or macOS, run:

eval $(crc oc-env)
Code language: JavaScript (javascript)

On Windows PowerShell, use the PowerShell command printed by crc oc-env.

Log in as the developer user:

oc login -u developer https://api.crc.testing:6443
Code language: JavaScript (javascript)

Use the password from:

crc console --credentials
Code language: JavaScript (javascript)

Verify the login:

oc whoami

Expected output:

developer

Check the node:

oc get nodes
Code language: JavaScript (javascript)

Expected output should show one OpenShift Local node in Ready status.


Part 4: Create a New Project

You can create the project from the web console or from CLI.

Option A: Create Project from Web Console

  1. Open the OpenShift web console.
  2. Log in as developer.
  3. Switch to the Developer perspective.
  4. Click the Project dropdown.
  5. Click Create Project.
  6. Enter the project name:
lab13-java-mysql
  1. Optional display name:
Lab 13 Java MySQL
  1. Click Create.

Option B: Create Project from CLI

Run:

oc new-project lab13-java-mysql
Code language: JavaScript (javascript)

Verify:

oc project

Expected output:

Using project "lab13-java-mysql"
Code language: JavaScript (javascript)

Part 5: Deploy MySQL from the Web Console

In this section, you will create MySQL using Import YAML in the OpenShift web console.

This creates:

  1. Secret
  2. PersistentVolumeClaim
  3. MySQL Deployment
  4. MySQL Service

Using YAML here is more reliable for a classroom lab than depending on an old ephemeral database template.


Open Import YAML

In the OpenShift web console:

  1. Make sure you are in project:
lab13-java-mysql
  1. Switch to Developer perspective.
  2. Click +Add.
  3. Click Import YAML.
  4. Paste the YAML below.
  5. Click Create.

YAML: MySQL Database

apiVersion: v1
kind: Secret
metadata:
  name: mysql-secret
  labels:
    app.kubernetes.io/name: mysql
    app.kubernetes.io/part-of: spring-petclinic-demo
type: Opaque
stringData:
  MYSQL_USER: petclinic
  MYSQL_PASSWORD: petclinic
  MYSQL_PASS: petclinic
  MYSQL_ROOT_PASSWORD: petclinic-root
  MYSQL_DATABASE: petclinic
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-data
  labels:
    app.kubernetes.io/name: mysql
    app.kubernetes.io/part-of: spring-petclinic-demo
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  labels:
    app: mysql
    app.kubernetes.io/name: mysql
    app.kubernetes.io/part-of: spring-petclinic-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql
        app.kubernetes.io/name: mysql
        app.kubernetes.io/part-of: spring-petclinic-demo
    spec:
      terminationGracePeriodSeconds: 30
      containers:
        - name: mysql
          image: registry.redhat.io/rhel9/mysql-80:latest
          imagePullPolicy: IfNotPresent
          ports:
            - name: mysql
              containerPort: 3306
              protocol: TCP
          env:
            - name: MYSQL_USER
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: MYSQL_USER
            - name: MYSQL_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: MYSQL_PASSWORD
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: MYSQL_ROOT_PASSWORD
            - name: MYSQL_DATABASE
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: MYSQL_DATABASE
          resources:
            requests:
              cpu: 100m
              memory: 512Mi
            limits:
              cpu: 500m
              memory: 1Gi
          readinessProbe:
            tcpSocket:
              port: 3306
            initialDelaySeconds: 20
            periodSeconds: 10
            timeoutSeconds: 3
          livenessProbe:
            tcpSocket:
              port: 3306
            initialDelaySeconds: 60
            periodSeconds: 20
            timeoutSeconds: 3
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
          volumeMounts:
            - name: mysql-data
              mountPath: /var/lib/mysql/data
      volumes:
        - name: mysql-data
          persistentVolumeClaim:
            claimName: mysql-data
---
apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    app: mysql
    app.kubernetes.io/name: mysql
    app.kubernetes.io/part-of: spring-petclinic-demo
spec:
  type: ClusterIP
  selector:
    app: mysql
  ports:
    - name: mysql
      protocol: TCP
      port: 3306
      targetPort: 3306
Code language: JavaScript (javascript)

Part 6: Understand the MySQL YAML

Secret

kind: Secret
metadata:
  name: mysql-secret

The Secret stores the database credentials.

Important values:

MYSQL_USER=petclinic
MYSQL_PASSWORD=petclinic
MYSQL_DATABASE=petclinic
MYSQL_ROOT_PASSWORD=petclinic-root

For this lab, the values are simple so students can understand the workflow.

In real production environments, do not commit plain database passwords to Git.


PersistentVolumeClaim

kind: PersistentVolumeClaim
metadata:
  name: mysql-data

The PVC stores the MySQL data files.

The MySQL data directory is mounted here:

/var/lib/mysql/data
Code language: JavaScript (javascript)

This means the database data can survive a MySQL pod restart.


Deployment

kind: Deployment
metadata:
  name: mysql

The Deployment runs one MySQL pod.

The strategy is:

strategy:
  type: Recreate

This is suitable for a single-instance database in a beginner lab because OpenShift stops the old pod before starting a new one.


Service

kind: Service
metadata:
  name: mysql

The Service gives the database a stable internal DNS name.

Other pods in the same project can connect to MySQL using:

mysql:3306
Code language: CSS (css)

This is why the Java application will use:

jdbc:mysql://mysql:3306/petclinic
Code language: JavaScript (javascript)

Part 7: Verify MySQL from the Web Console

In the web console:

  1. Go to Developer perspective.
  2. Open Topology.
  3. Confirm that you see a workload named:
mysql
  1. Click the mysql workload.
  2. Open the Resources tab.
  3. Confirm that the pod is running.
  4. Open the Logs tab.

The MySQL pod should start successfully.


Part 8: Verify MySQL from CLI

Set the project:

oc project lab13-java-mysql

Check resources:

oc get deploy,pod,svc,pvc,secret
Code language: JavaScript (javascript)

Expected resources:

deployment.apps/mysql
pod/mysql-xxxxx
service/mysql
persistentvolumeclaim/mysql-data
secret/mysql-secret

Check rollout:

oc rollout status deployment/mysql

Expected output:

deployment "mysql" successfully rolled out
Code language: JavaScript (javascript)

Check the PVC:

oc get pvc mysql-data
Code language: JavaScript (javascript)

Expected status:

Bound

Check MySQL logs:

oc logs deployment/mysql

Part 9: Test MySQL Login

Find the MySQL pod:

MYSQL_POD=$(oc get pod -l app=mysql -o jsonpath='{.items[0].metadata.name}')
echo "$MYSQL_POD"
Code language: PHP (php)

Open a shell inside the MySQL pod:

oc rsh "$MYSQL_POD"
Code language: JavaScript (javascript)

Inside the pod, connect to MySQL:

mysql -u petclinic -ppetclinic petclinic

Run:

SHOW DATABASES;

You should see:

petclinic

Exit MySQL:

exit
Code language: PHP (php)

Exit the pod shell:

exit
Code language: PHP (php)

Part 10: Deploy the Java Spring PetClinic Application from Git

Now you will deploy the Java application from source code.

The application source repository is:

https://github.com/redhat-developer-demos/spring-petclinic
Code language: JavaScript (javascript)

This repository contains a Spring Boot PetClinic application prepared for OpenShift Source-to-Image.


Open Import from Git

In the OpenShift web console:

  1. Make sure you are in project:
lab13-java-mysql
  1. Switch to Developer perspective.
  2. Click +Add.
  3. Click Import from Git or From Git.

The exact label depends on your OpenShift console version.


Enter Git Repository URL

In the Git repository URL field, enter:

https://github.com/redhat-developer-demos/spring-petclinic
Code language: JavaScript (javascript)

OpenShift will inspect the repository.

You may see an import warning because the repository contains older metadata such as a devfile or Dockerfile. This is expected for this lab.

The correct action is to manually choose the Builder Image strategy.


Part 11: Select the Correct Import Strategy

Click:

Edit Import Strategy

Select:

Builder Image

For the builder image, select:

Java

For the Java version, select:

OpenJDK 11

If OpenJDK 11 is not shown in your environment, use the available Java builder image recommended by your instructor.

For this specific Spring PetClinic sample, Java 11 is the safest choice because the sample repository is older and its Dockerfile also references OpenJDK 11.


Part 12: Configure Application Details

Scroll to the application details section.

Use the following values:

FieldValue
Application namespring-petclinic-demo
Namespring-petclinic
Resource typeDeployment

Set:

Application name: spring-petclinic-demo
Name: spring-petclinic
Resource type: Deployment

Make sure the selected resource type is:

Deployment

Do not select:

DeploymentConfig

Part 13: Create a Route for the Java Application

Open Advanced options.

Enable:

Create a route to the application

This is needed because Spring PetClinic is a web application.

The Route will allow you to open the application in your browser.


Part 14: Add Environment Variables

In Advanced options, open the Environment variables section.

Add the following environment variables:

NameValue
SPRING_PROFILES_ACTIVEmysql
MYSQL_URLjdbc:mysql://mysql:3306/petclinic

The final values should be:

SPRING_PROFILES_ACTIVE=mysql
MYSQL_URL=jdbc:mysql://mysql:3306/petclinic
Code language: JavaScript (javascript)

These values tell Spring PetClinic to:

  1. Use the MySQL Spring profile.
  2. Connect to MySQL using the OpenShift Service named mysql.
  3. Use the petclinic database.

The sample application defaults to this database username and password:

Username: petclinic
Password: petclinic
Code language: HTTP (http)

These values match the MySQL Secret created earlier.


Optional: Add Explicit MySQL User and Password

If your instructor wants students to make credentials explicit, add these two environment variables also:

NameValue
MYSQL_USERpetclinic
MYSQL_PASSpetclinic

So the complete environment variable list becomes:

SPRING_PROFILES_ACTIVE=mysql
MYSQL_URL=jdbc:mysql://mysql:3306/petclinic
MYSQL_USER=petclinic
MYSQL_PASS=petclinic
Code language: JavaScript (javascript)

For the beginner lab, either approach works because the application defaults already match the lab database values.


Part 15: Create the Java Application

Review the form.

You should have:

SettingExpected Value
Projectlab13-java-mysql
Git Repositoryhttps://github.com/redhat-developer-demos/spring-petclinic
Import StrategyBuilder Image
Builder ImageJava
Java VersionOpenJDK 11 if available
Application namespring-petclinic-demo
Namespring-petclinic
Resource typeDeployment
Create routeEnabled
SPRING_PROFILES_ACTIVEmysql
MYSQL_URLjdbc:mysql://mysql:3306/petclinic

Click:

Create

OpenShift will now start a Source-to-Image build.


Part 16: Watch the Java Build

After clicking Create, OpenShift redirects you to the Topology view.

You should see:

spring-petclinic

The build may take several minutes because Maven dependencies must be downloaded.

To view build progress from the web console:

  1. Click the spring-petclinic workload.
  2. Open the Resources tab.
  3. Find the build.
  4. Open the build details.
  5. Click Logs.

Typical build stages:

Cloning Git repository
Running Maven build
Creating application artifact
Assembling S2I image
Pushing image to OpenShift internal registry
Starting deployment rollout

Part 17: Watch the Build from CLI

From your terminal, run:

oc project lab13-java-mysql

List BuildConfigs:

oc get bc
Code language: JavaScript (javascript)

Expected output:

spring-petclinic

List builds:

oc get builds
Code language: JavaScript (javascript)

Expected output:

spring-petclinic-1

Follow build logs:

oc logs -f bc/spring-petclinic

Wait until the build completes.

Expected build status:

oc get builds
Code language: JavaScript (javascript)

Expected result:

spring-petclinic-1   Complete

Part 18: Verify the Application Deployment

Check the Deployment:

oc get deployment spring-petclinic
Code language: JavaScript (javascript)

Expected output:

NAME               READY   UP-TO-DATE   AVAILABLE
spring-petclinic   1/1     1            1

Check rollout status:

oc rollout status deployment/spring-petclinic

Expected output:

deployment "spring-petclinic" successfully rolled out
Code language: JavaScript (javascript)

Check pods:

oc get pods
Code language: JavaScript (javascript)

Expected output should include:

mysql-xxxxx                  1/1     Running
spring-petclinic-xxxxx       1/1     Running

Check Java app logs:

oc logs deployment/spring-petclinic

You should see Spring Boot startup logs.


Part 19: Verify Service and Route

Check services:

oc get svc
Code language: JavaScript (javascript)

Expected services:

mysql
spring-petclinic

Check routes:

oc get route
Code language: JavaScript (javascript)

Expected route:

spring-petclinic

Store the app URL:

APP_URL="http://$(oc get route spring-petclinic -o jsonpath='{.spec.host}')"
echo "$APP_URL"
Code language: PHP (php)

Test the route:

curl -I "$APP_URL"
Code language: JavaScript (javascript)

Expected result should include an HTTP response.

Example:

HTTP/1.1 200 OK
Code language: HTTP (http)

Open the URL in your browser.

You should see the Spring PetClinic application.


Part 20: Test the Application in Browser

In the Spring PetClinic UI:

  1. Open the application route.
  2. Click Find owners.
  3. Click Find Owner without entering anything.
  4. You should see the list of sample owners.
  5. Click Add Owner.
  6. Add a new owner.
  7. Save.
  8. Search again and confirm the new owner appears.

This confirms:

  1. The Java application is running.
  2. The app can connect to MySQL.
  3. The app can write data to MySQL.
  4. The app can read data from MySQL.

Part 21: Verify Data in MySQL

Find the MySQL pod:

MYSQL_POD=$(oc get pod -l app=mysql -o jsonpath='{.items[0].metadata.name}')
echo "$MYSQL_POD"
Code language: PHP (php)

Run MySQL command directly:

oc exec -it "$MYSQL_POD" -- mysql -u petclinic -ppetclinic petclinic
Code language: JavaScript (javascript)

Inside MySQL, run:

SHOW TABLES;

Expected output should include tables such as:

owners
pets
types
vets
visits
specialties
vet_specialties

Check owners:

SELECT id, first_name, last_name, city FROM owners LIMIT 10;

Exit MySQL:

exit
Code language: PHP (php)

Part 22: Prove MySQL Persistence

In this section, you will restart the MySQL pod and confirm that data is still present.

Scale MySQL down:

oc scale deployment/mysql --replicas=0

Check pods:

oc get pods
Code language: JavaScript (javascript)

Scale MySQL back up:

oc scale deployment/mysql --replicas=1

Wait for rollout:

oc rollout status deployment/mysql

Restart the Java app so it reconnects cleanly:

oc rollout restart deployment/spring-petclinic
oc rollout status deployment/spring-petclinic

Open the application again in your browser.

Check whether the owner data is still present.

If the data is still available, the PVC is working.


Part 23: Understand the Complete Flow

When you completed this lab, OpenShift performed the following:

1. Created a MySQL Secret.
2. Created a MySQL PVC.
3. Started a MySQL Deployment.
4. Created a MySQL Service named mysql.
5. Imported Java source code from GitHub.
6. Used a Java builder image.
7. Created a BuildConfig.
8. Started a Build.
9. Built a runnable image using S2I.
10. Stored the image in an ImageStream.
11. Started a Spring PetClinic Deployment.
12. Created a Spring PetClinic Service.
13. Created a Spring PetClinic Route.
14. Exposed the app in the browser.
15. Connected the Java app to MySQL using internal service discovery.
Code language: JavaScript (javascript)

Part 24: Student Validation Checklist

Students should verify:

CheckCommandExpected Result
Current projectoc projectlab13-java-mysql
MySQL deploymentoc get deploy mysql1/1 ready
MySQL serviceoc get svc mysqlService exists
MySQL PVCoc get pvc mysql-dataBound
Java BuildConfigoc get bc spring-petclinicExists
Java buildoc get buildsBuild Complete
ImageStreamoc get is spring-petclinicExists
Java deploymentoc get deploy spring-petclinic1/1 ready
Java serviceoc get svc spring-petclinicService exists
Java routeoc get route spring-petclinicRoute exists
Browser testOpen routePetClinic UI opens
Database testQuery owners tableData visible

Part 25: Full CLI Validation Script

Run this script after completing the lab:

oc project lab13-java-mysql

echo "Checking core resources..."
oc get deploy,pod,svc,route,pvc,secret

echo "Checking MySQL rollout..."
oc rollout status deployment/mysql

echo "Checking Spring PetClinic build resources..."
oc get bc
oc get builds
oc get imagestream

echo "Checking Spring PetClinic rollout..."
oc rollout status deployment/spring-petclinic

echo "Checking application route..."
APP_URL="http://$(oc get route spring-petclinic -o jsonpath='{.spec.host}')"
echo "$APP_URL"
curl -I "$APP_URL"

echo "Checking MySQL pod..."
MYSQL_POD=$(oc get pod -l app=mysql -o jsonpath='{.items[0].metadata.name}')
echo "$MYSQL_POD"

echo "Checking MySQL tables..."
oc exec "$MYSQL_POD" -- mysql -u petclinic -ppetclinic petclinic -e "SHOW TABLES;"

echo "Checking owners table..."
oc exec "$MYSQL_POD" -- mysql -u petclinic -ppetclinic petclinic -e "SELECT id, first_name, last_name FROM owners LIMIT 5;"
Code language: PHP (php)

Expected result:

  1. MySQL Deployment is ready.
  2. MySQL PVC is Bound.
  3. Java build is Complete.
  4. Java Deployment is ready.
  5. Route exists.
  6. Browser or curl can reach the app.
  7. MySQL contains PetClinic tables.
  8. Owners table returns rows.

Part 26: Optional CLI-Only Equivalent

The main lab uses the web console.

For instructor testing, the same Java application can be created from CLI if the Java builder image stream exists in the cluster.

First, create the project:

oc new-project lab13-java-mysql-cli
Code language: JavaScript (javascript)

Apply the MySQL YAML from this lab.

Then create the Java application from Git:

oc new-app java:11~https://github.com/redhat-developer-demos/spring-petclinic --name=spring-petclinic \
  -e SPRING_PROFILES_ACTIVE=mysql \
  -e MYSQL_URL=jdbc:mysql://mysql:3306/petclinic
Code language: JavaScript (javascript)

Expose it:

oc expose svc/spring-petclinic

Watch build logs:

oc logs -f bc/spring-petclinic

Check rollout:

oc rollout status deployment/spring-petclinic

This CLI section is optional and should be used mainly by instructors.


Part 27: Troubleshooting

Problem 1: MySQL Pod Shows ImagePullBackOff

Symptom

ImagePullBackOff
ErrImagePull

Check

oc get pods
oc describe pod -l app=mysql
Code language: JavaScript (javascript)

Possible Causes

  1. Red Hat pull secret is missing or invalid.
  2. The machine is connected to VPN and cannot reach the registry.
  3. Internet access is blocked.
  4. Registry access is temporarily unavailable.

Fix

Check CRC status:

crc status

Check pod events:

oc get events --sort-by=.lastTimestamp
Code language: JavaScript (javascript)

If registry access is the issue, ask the instructor to verify the OpenShift Local pull secret and registry access.


Problem 2: MySQL PVC Is Pending

Symptom

oc get pvc mysql-data
Code language: JavaScript (javascript)

Shows:

Pending

Check

oc describe pvc mysql-data
oc get storageclass
Code language: JavaScript (javascript)

Possible Causes

  1. No default StorageClass.
  2. OpenShift Local storage is not ready.
  3. Cluster is still starting.

Fix

Wait a short time and check again:

oc get pvc mysql-data
Code language: JavaScript (javascript)

If it remains Pending, ask the instructor to verify OpenShift Local storage.


Problem 3: Import from Git Shows โ€œImport Is Not Possibleโ€

Symptom

The web console shows an import error or warning after entering:

https://github.com/redhat-developer-demos/spring-petclinic
Code language: JavaScript (javascript)

Explanation

This can happen because the repository contains multiple possible build hints, such as a Dockerfile or devfile.

This is expected for this lab.

Fix

Click:

Edit Import Strategy

Then select:

Builder Image

Choose:

Java

Then continue.


Problem 4: Java Build Fails

Check Build Logs

oc logs -f bc/spring-petclinic

Check build status:

oc get builds
Code language: JavaScript (javascript)

Describe the failed build:

oc describe build spring-petclinic-1

Possible Causes

  1. Maven dependency download failed.
  2. Network/VPN issue.
  3. Wrong Java builder image.
  4. OpenShift Local does not have enough memory.
  5. GitHub access is blocked.
  6. The repository import strategy was not changed to Builder Image.

Fix

Use the Java Builder Image strategy.

Prefer OpenJDK 11 for this sample if available.

Try the build again:

oc start-build spring-petclinic

Follow logs:

oc logs -f bc/spring-petclinic

Problem 5: Java Pod Is CrashLoopBackOff

Check

oc get pods
oc logs deployment/spring-petclinic
Code language: JavaScript (javascript)

Common Cause

The application cannot connect to MySQL.

Check whether MySQL is running:

oc get deploy mysql
oc get svc mysql
oc get pods -l app=mysql
Code language: JavaScript (javascript)

Check whether the Java app has the correct environment variables:

oc set env deployment/spring-petclinic --list
Code language: JavaScript (javascript)

Required values:

SPRING_PROFILES_ACTIVE=mysql
MYSQL_URL=jdbc:mysql://mysql:3306/petclinic
Code language: JavaScript (javascript)

If missing, add them:

oc set env deployment/spring-petclinic SPRING_PROFILES_ACTIVE=mysql MYSQL_URL=jdbc:mysql://mysql:3306/petclinic
Code language: JavaScript (javascript)

Restart the app:

oc rollout restart deployment/spring-petclinic
oc rollout status deployment/spring-petclinic

Problem 6: Application Opens but Data Is Missing

Possible Causes

  1. App started before MySQL was ready.
  2. App is using H2 instead of MySQL.
  3. SPRING_PROFILES_ACTIVE=mysql is missing.
  4. MYSQL_URL is incorrect.
  5. Database schema was not initialized.

Check Environment

oc set env deployment/spring-petclinic --list
Code language: JavaScript (javascript)

Check logs:

oc logs deployment/spring-petclinic

Restart the application:

oc rollout restart deployment/spring-petclinic
oc rollout status deployment/spring-petclinic

Then check MySQL tables again:

MYSQL_POD=$(oc get pod -l app=mysql -o jsonpath='{.items[0].metadata.name}')
oc exec "$MYSQL_POD" -- mysql -u petclinic -ppetclinic petclinic -e "SHOW TABLES;"
Code language: PHP (php)

Problem 7: Route Does Not Open

Check Route

oc get route spring-petclinic
Code language: JavaScript (javascript)

If no route exists, create one:

oc expose svc/spring-petclinic

Check service:

oc get svc spring-petclinic
Code language: JavaScript (javascript)

Check endpoints:

oc get endpoints spring-petclinic
Code language: JavaScript (javascript)

If endpoints are empty, the Service is not pointing to a running pod.

Check labels:

oc get pods --show-labels
oc describe svc spring-petclinic
Code language: JavaScript (javascript)

Problem 8: BuildConfig Not Found

Symptom

oc get bc spring-petclinic
Code language: JavaScript (javascript)

Returns NotFound.

Possible Causes

  1. You are in the wrong project.
  2. The app was not created from Git.
  3. The name is different.
  4. The import failed.

Fix

Check current project:

oc project

Switch project:

oc project lab13-java-mysql

List all resources:

oc get all
Code language: JavaScript (javascript)

List BuildConfigs:

oc get bc
Code language: JavaScript (javascript)

Part 28: Cleanup

To remove all lab resources, delete the project.

Cleanup from Web Console

  1. Switch to the Administrator perspective.
  2. Go to Home > Projects.
  3. Select:
lab13-java-mysql
  1. Click Delete Project.
  2. Confirm deletion.

Cleanup from CLI

Run:

oc delete project lab13-java-mysql
Code language: JavaScript (javascript)

Verify:

oc get project lab13-java-mysql
Code language: JavaScript (javascript)

Expected result:

Error from server (NotFound): projects.project.openshift.io "lab13-java-mysql" not found
Code language: JavaScript (javascript)

Part 29: Lab Summary

In this lab, you deployed a complete Java and database application on OpenShift.

You created:

ResourcePurpose
SecretStored MySQL credentials
PersistentVolumeClaimStored MySQL data
MySQL DeploymentRan the database
MySQL ServiceProvided internal database access
BuildConfigDefined the Java source build
BuildBuilt the Java app image
ImageStreamTracked the built image
Java DeploymentRan Spring PetClinic
Java ServiceProvided internal app access
RouteExposed the app to the browser

You verified that:

  1. MySQL runs inside OpenShift.
  2. MySQL has persistent storage.
  3. Spring PetClinic builds from Git source code.
  4. OpenShift S2I creates a runnable application image.
  5. The Java app connects to MySQL using the internal service name mysql.
  6. The app is available in the browser through an OpenShift Route.
  7. Data can be written to and read from MySQL.

Part 30: Review Questions

Question 1

What is the purpose of Source-to-Image?

Answer

Source-to-Image builds a runnable container image by combining application source code with a builder image.


Question 2

What is the purpose of BuildConfig?

Answer

BuildConfig defines how OpenShift builds the application, including the Git repository, build strategy, builder image, triggers, and output image.


Question 3

What is the purpose of ImageStream?

Answer

ImageStream tracks the image built by OpenShift and allows the Deployment to consume that image.


Question 4

Why does MySQL not have a Route?

Answer

MySQL is an internal database service. It should normally be accessed only by applications inside the cluster through a Service.


Question 5

What is the internal hostname for MySQL?

Answer

mysql

Question 6

What JDBC URL does Spring PetClinic use?

Answer

jdbc:mysql://mysql:3306/petclinic
Code language: JavaScript (javascript)

Question 7

Which environment variable tells Spring Boot to use MySQL?

Answer

SPRING_PROFILES_ACTIVE=mysql

Question 8

Which OpenShift resource exposes Spring PetClinic to the browser?

Answer

Route.


Question 9

Which OpenShift resource stores MySQL data?

Answer

PersistentVolumeClaim.


Question 10

Which command shows the Java build logs?

Answer

oc logs -f bc/spring-petclinic

Part 31: Instructor Notes

This lab is designed as a modern replacement for the older Java PetClinic lab.

The original lab used:

  1. Developer Sandbox.
  2. MySQL Ephemeral template.
  3. Simple direct environment variables.
  4. Minimal CLI validation.

This replacement uses:

  1. OpenShift Local.
  2. MySQL Deployment.
  3. Secret for credentials.
  4. PVC for storage.
  5. Service for internal database access.
  6. S2I Java build from Git.
  7. Deployment instead of DeploymentConfig.
  8. Route for browser access.
  9. CLI validation.
  10. Troubleshooting.

For production-grade Java/database workloads, students should later learn:

  1. Database Operators.
  2. Managed database services.
  3. Backup and restore.
  4. Secret rotation.
  5. TLS database connections.
  6. Readiness and liveness probes based on real commands.
  7. Resource tuning.
  8. Horizontal Pod Autoscaler for stateless app tier.
  9. NetworkPolicy.
  10. GitOps-based deployment.
  11. CI/CD with OpenShift Pipelines.
  12. Image vulnerability scanning.

Part 32: Instructor Pre-Validation Checklist

Before giving this lab to students, run:

crc status
oc whoami
oc get nodes
oc get storageclass
Code language: JavaScript (javascript)

Create a test project:

oc new-project lab13-validation
Code language: JavaScript (javascript)

Apply the MySQL YAML from this lab.

Validate MySQL:

oc rollout status deployment/mysql
oc get pvc mysql-data
MYSQL_POD=$(oc get pod -l app=mysql -o jsonpath='{.items[0].metadata.name}')
oc exec "$MYSQL_POD" -- mysql -u petclinic -ppetclinic petclinic -e "SHOW DATABASES;"
Code language: PHP (php)

Then validate the Java build through the web console or CLI.

Clean up:

oc delete project lab13-validation
Code language: JavaScript (javascript)

If MySQL starts, the Java build completes, and the route opens successfully, the lab is ready for students.


Final Outcome

You have successfully deployed a Java Spring Boot application with MySQL on OpenShift.

You now understand this complete OpenShift workflow:

MySQL Secret
  -> MySQL PVC
  -> MySQL Deployment
  -> MySQL Service
  -> Java Source Code from Git
  -> S2I Build
  -> BuildConfig
  -> ImageStream
  -> Java Deployment
  -> Java Service
  -> Java Route
  -> Browser
Code language: JavaScript (javascript)

This is a very important real-world pattern because many enterprise applications need both an application tier and a database tier, and OpenShift provides the tools to build, deploy, expose, and validate that workflow.

Find Trusted Cardiac Hospitals

Compare heart hospitals by city and services โ€” all in one place.

Explore Hospitals
Iโ€™m a DevOps/SRE/DevSecOps/Cloud Expert passionate about sharing knowledge and experiences. I have worked at <a href="https://www.cotocus.com/">Cotocus</a>. I share tech blog at <a href="https://www.devopsschool.com/">DevOps School</a>, travel stories at <a href="https://www.holidaylandmark.com/">Holiday Landmark</a>, stock market tips at <a href="https://www.stocksmantra.in/">Stocks Mantra</a>, health and fitness guidance at <a href="https://www.mymedicplus.com/">My Medic Plus</a>, product reviews at <a href="https://www.truereviewnow.com/">TrueReviewNow</a> , and SEO strategies at <a href="https://www.wizbrand.com/">Wizbrand.</a> Do you want to learn <a href="https://www.quantumuting.com/">Quantum Computing</a>? <strong>Please find my social handles as below;</strong> <a href="https://www.rajeshkumar.xyz/">Rajesh Kumar Personal Website</a> <a href="https://www.youtube.com/TheDevOpsSchool">Rajesh Kumar at YOUTUBE</a> <a href="https://www.instagram.com/rajeshkumarin">Rajesh Kumar at INSTAGRAM</a> <a href="https://x.com/RajeshKumarIn">Rajesh Kumar at X</a> <a href="https://www.facebook.com/RajeshKumarLog">Rajesh Kumar at FACEBOOK</a> <a href="https://www.linkedin.com/in/rajeshkumarin/">Rajesh Kumar at LINKEDIN</a> <a href="https://www.wizbrand.com/rajeshkumar">Rajesh Kumar at WIZBRAND</a> <a href="https://www.rajeshkumar.xyz/dailylogs">Rajesh Kumar DailyLogs</a>

Related Posts

Best DevOps Tools in 2024

hereโ€™s a clear, structured breakdown of the Best DevOps Tools (grouped by categories), so you can use it for learning, training, or posts. ๐Ÿš€ Best DevOps Tools…

Read More

OpenShift Tutorial โ€“ Deploy and Access Your First Applications using OpenShift Local

How to install oc? OpenShift: How to Install OpenShift CLI oc How to login? Login to the Openshift using Web Console and CLI using oc Copy the admin…

Read More

OpenShift Lab 14: Setting Up and Using OpenShift Serverless Functions on OpenShift Local

Lab Objective In this lab, you will install and use OpenShift Serverless Functions on OpenShift Local. You will create a simple Node.js serverless function, deploy it to…

Read More

OpenShift Lab 12: Deploy an Application from an Existing Container Image Using the OpenShift Web Console

Lab Objective In this lab, you will deploy an application on OpenShift from an existing container image. This lab is different from building an application from source…

Read More

OpenShift: How to Install OpenShift CLIย oc

Option – 1 – REDHAT Websites URL – https://access.redhat.com/downloads/content/290/ver=4.18/rhel—9/4.18.11/x86_64/product-software Option – 2 – OKD Websites The OKD (Origin Community Distribution of Kubernetes for OpenShift) is the open-source…

Read More

OpenShift Lab 11: Build and Deploy an Application from Source Code Using the OpenShift Web Console

Lab Objective In this lab, you will build and deploy a web application from source code stored in a Git repository using the OpenShift web console. You…

Read More
Subscribe
Notify of
guest
1 Comment
Newest
Oldest Most Voted
Skylar Bennett
Skylar Bennett
12 days ago

While the guide walks through deploying a Java application on Kubernetes effectively, it would be beneficial to address some day-two operational concerns. Java workloads running in containers often require JVM tuning to work efficiently within CPU and memory constraints. Additionally, discussing health checks, deployment rollback strategies, and monitoring approaches such as metrics collection and tracing would provide readers with a better understanding of how to keep Java applications reliable and observable in production Kubernetes clusters.

1
0
Would love your thoughts, please comment.x
()
x