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 code. In the previous source-code lab, OpenShift pulled code from Git and built a container image. In this lab, the container image already exists in an external container registry, so OpenShift only needs to pull the image and run it.
By the end of this lab, you will understand how OpenShift deploys a ready-made container image using the web console.
What You Will Learn
You will learn how to:
- Start OpenShift Local.
- Log in to the OpenShift web console.
- Create a new project.
- Deploy an application from an external container image.
- Use the OpenShift web console Container images option.
- Create a Deployment.
- Create a Service.
- Create a Route.
- Open the application in a browser.
- Validate the deployment using the
ocCLI. - Inspect pods, services, routes, labels, and logs.
- Scale the application.
- Troubleshoot common image deployment issues.
- Clean up the lab environment.
Lab Scenario
You already have a container image stored in a registry.
You want to run that image on OpenShift without building source code.
For this lab, you will use the following public sample image:
quay.io/openshiftroadshow/parksmap:latest
This image is used in Red Hatโs OpenShift learning material as a sample front-end application.
Lab Architecture
External Container Registry
|
v
OpenShift pulls image
|
v
Deployment
|
v
ReplicaSet
|
v
Pod
|
v
Service
|
v
Route
|
v
Browser
Key Difference: Source Code Build vs Container Image Deployment
| Area | Build from Source Code | Deploy from Container Image |
|---|---|---|
| Input | Git repository | Existing container image |
| Build required? | Yes | No |
| BuildConfig created? | Yes | No |
| ImageStream may be created? | Yes | Not always |
| Faster? | Usually slower | Usually faster |
| Best for | Developers building code | Teams deploying already-built images |
| Example | Node.js app from GitHub | App image from Quay, Docker Hub, or internal registry |
OpenShift Resources Created in This Lab
When you deploy from a container image, OpenShift creates these resources:
| Resource | Purpose |
|---|---|
| Project | Isolated namespace for this lab |
| Deployment | Defines and manages the running application |
| ReplicaSet | Maintains the desired number of pods |
| Pod | Runs the container |
| Service | Provides stable internal access to the pod |
| Route | Provides browser access from outside the cluster |
Unlike a source-code build lab, this lab does not create a BuildConfig or Build, because no build is needed.
Part 1: Prerequisites
Required Tools
You need:
- OpenShift Local installed.
crccommand available.occommand available.- Browser access to the OpenShift web console.
- Internet access from OpenShift Local to pull the container image.
Recommended Local Machine Resources
Use at least:
| Resource | Recommended |
|---|---|
| CPU | 4 cores or more |
| Memory | 12 GB or more |
| Disk | 35 GB or more |
Part 2: Start OpenShift Local
Open a terminal.
Check 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 startup may take several minutes.
To view the OpenShift Local credentials:
crc console --credentials
Code language: JavaScript (javascript)
To 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, copy and run the 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 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
Option A: Create Project from Web Console
- Open the OpenShift web console.
- Log in as
developer. - Switch to the Developer perspective.
- Click the Project dropdown.
- Click Create Project.
- Enter:
lab12-container-image
- Optional display name:
Lab 12 Container Image
- Click Create.
Option B: Create Project from CLI
Run:
oc new-project lab12-container-image
Code language: JavaScript (javascript)
Verify:
oc project
Expected output:
Using project "lab12-container-image"
Code language: JavaScript (javascript)
Part 5: Deploy the Application from a Container Image
In the OpenShift web console:
- Make sure you are in the project:
lab12-container-image
- Switch to the Developer perspective.
- Click +Add.
- Click Container images.
Depending on your OpenShift version, you may also see this from the quick-create + icon.
Image Section
Select:
Image name from external registry
Code language: JavaScript (javascript)
In the image name field, enter:
quay.io/openshiftroadshow/parksmap:latest
OpenShift will validate the image.
If validation takes time, wait for a few seconds.
Runtime Icon
For the runtime icon, you can select a suitable icon such as:
Java
or keep the default detected icon.
The icon does not affect the deployment. It only changes how the workload appears in the Topology view.
Part 6: Configure General Settings
Scroll to the General section.
Use these values:
| Field | Value |
|---|---|
| Application name | national-parks-app |
| Name | parksmap |
Enter:
Application name: national-parks-app
Name: parksmap
The Application name groups related components visually in the Topology view.
The Name is used for the actual OpenShift resources such as Deployment, Service, and Route.
Part 7: Select Resource Type
In the Resource type section, select:
Deployment
Do not select DeploymentConfig.
A Deployment is the standard Kubernetes workload resource and is the best option for current beginner labs.
Part 8: Create a Route
In the Advanced options section, make sure this is enabled:
Create a route to the application
A Route is required because this is a web application and students need to open it in a browser.
Without a Route, the application would run inside the cluster, but it would not be accessible from your browser.
Part 9: Add Labels
Click the Labels section.
Add the following labels:
app=national-parks-app
component=parksmap
role=frontend
These labels help organize the application and make it easier to identify resources.
They are also useful for selectors, filtering, and the Topology view.
Part 10: Create the Application
Review your configuration.
| Setting | Expected Value |
|---|---|
| Project | lab12-container-image |
| Image source | External registry |
| Image | quay.io/openshiftroadshow/parksmap:latest |
| Application name | national-parks-app |
| Name | parksmap |
| Resource type | Deployment |
| Create route | Enabled |
| Labels | app=national-parks-app, component=parksmap, role=frontend |
Click:
Create
OpenShift now creates the application.
Because this lab uses an existing image, there is no build step.
Part 11: Watch the Application in Topology
After clicking Create, OpenShift redirects you to the Topology view.
You should see a workload named:
parksmap
Wait until the workload shows as running.
Click the parksmap workload.
You should see tabs or sections such as:
- Details
- Resources
- Observe
- Logs
The exact layout may vary slightly by OpenShift version.
Part 12: Open the Application in a Browser
In the Topology view:
- Click the
parksmapworkload. - Click the external URL or open-route icon.
- A browser tab should open.
You should see the ParksMap web application page.
If the page does not load immediately, wait for the pod to become ready and refresh the browser.
Part 13: Validate the Deployment Using CLI
Set the project:
oc project lab12-container-image
List all created resources:
oc get all
Code language: JavaScript (javascript)
Expected resources include:
deployment.apps/parksmap
replicaset.apps/parksmap-xxxxx
pod/parksmap-xxxxx
service/parksmap
route.route.openshift.io/parksmap
List only the important resources:
oc get deployment,pod,svc,route
Code language: JavaScript (javascript)
Expected output should show:
deployment.apps/parksmap
pod/parksmap-xxxxx
service/parksmap
route.route.openshift.io/parksmap
Part 14: Check the Deployment
Run:
oc get deployment parksmap
Code language: JavaScript (javascript)
Expected output:
NAME READY UP-TO-DATE AVAILABLE AGE
parksmap 1/1 1 1 ...
Check rollout status:
oc rollout status deployment/parksmap
Expected output:
deployment "parksmap" successfully rolled out
Code language: JavaScript (javascript)
Describe the Deployment:
oc describe deployment parksmap
Check the image used by the Deployment:
oc get deployment parksmap -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'
Code language: PHP (php)
Expected output:
quay.io/openshiftroadshow/parksmap:latest
Part 15: Check the Pod
Run:
oc get pods
Code language: JavaScript (javascript)
Expected output:
NAME READY STATUS RESTARTS AGE
parksmap-xxxxxxxxxx-xxxxx 1/1 Running 0 ...
View pod logs:
oc logs deployment/parksmap
If the pod is not running, describe it:
oc describe pod -l deployment=parksmap
If that selector does not work in your environment, list labels first:
oc get pods --show-labels
Code language: JavaScript (javascript)
Then use the correct label shown in your output.
Part 16: Check the Service
Run:
oc get svc parksmap
Code language: JavaScript (javascript)
Expected output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
parksmap ClusterIP ... <none> 8080/TCP ...
Code language: HTML, XML (xml)
The Service provides internal cluster access to the application.
Inside the same OpenShift project, other pods can reach this app using:
http://parksmap:8080
Code language: JavaScript (javascript)
Describe the Service:
oc describe svc parksmap
Check endpoints:
oc get endpoints parksmap
Code language: JavaScript (javascript)
The endpoint should point to the running pod IP and port.
If the endpoint is empty, the Service is not matching the pod labels.
Part 17: Check the Route
Run:
oc get route parksmap
Code language: JavaScript (javascript)
Expected output:
NAME HOST/PORT SERVICES PORT
parksmap parksmap-lab12-container-image.apps-crc.testing parksmap 8080
The exact hostname may be different.
Store the app URL:
APP_URL="http://$(oc get route parksmap -o jsonpath='{.spec.host}')"
echo "$APP_URL"
Code language: PHP (php)
Test the route:
curl -I "$APP_URL"
Code language: JavaScript (javascript)
Expected result:
HTTP/1.1 200 OK
Code language: HTTP (http)
A different successful HTTP response is also acceptable, depending on the image behavior.
Part 18: Confirm That No Build Was Created
This lab deploys an existing image. It does not build a new image.
Check BuildConfigs:
oc get buildconfig
Code language: JavaScript (javascript)
Expected output:
No resources found in lab12-container-image namespace.
Code language: PHP (php)
Check Builds:
oc get builds
Code language: JavaScript (javascript)
Expected output:
No resources found in lab12-container-image namespace.
Code language: PHP (php)
This is correct.
No BuildConfig is needed because the container image already exists.
Part 19: Scale the Application
You can scale the Deployment from the web console or CLI.
Option A: Scale from Web Console
- Go to Developer perspective.
- Open Topology.
- Click the
parksmapworkload. - Open the Details tab.
- Increase the pod count from
1to2.
Wait until two pods are running.
Option B: Scale from CLI
Run:
oc scale deployment/parksmap --replicas=2
Check pods:
oc get pods
Code language: JavaScript (javascript)
Expected result:
Two parksmap pods should be running.
Check Deployment:
oc get deployment parksmap
Code language: JavaScript (javascript)
Expected output:
READY 2/2
Scale back to one pod:
oc scale deployment/parksmap --replicas=1
Verify:
oc get deployment parksmap
Code language: JavaScript (javascript)
Expected output:
READY 1/1
Part 20: Update the Container Image Tag
In real projects, teams often deploy a new application version by changing the image tag.
For this beginner lab, do not change the image unless your instructor provides a tested tag.
You can view the current image:
oc get deployment parksmap -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'
Code language: PHP (php)
Example output:
quay.io/openshiftroadshow/parksmap:latest
If you had another valid image tag, the update command would look like this:
oc set image deployment/parksmap parksmap=quay.io/openshiftroadshow/parksmap:<new-tag>
Code language: HTML, XML (xml)
Then check rollout:
oc rollout status deployment/parksmap
For this lab, keep the original image.
Part 21: Roll Out Restart
You can restart the application without changing the image.
Run:
oc rollout restart deployment/parksmap
Watch rollout:
oc rollout status deployment/parksmap
Check pods:
oc get pods
Code language: JavaScript (javascript)
You should see a new pod replacing the old pod.
Part 22: Student Checkpoint
Students should be able to answer:
| Question | Expected Answer |
|---|---|
| Did OpenShift build the image in this lab? | No |
| Where did the image come from? | External container registry |
| Which image did we use? | quay.io/openshiftroadshow/parksmap:latest |
| Which resource runs the app? | Deployment |
| Which resource creates the pod? | Deployment through ReplicaSet |
| Which resource gives internal access? | Service |
| Which resource gives browser access? | Route |
| Why was no BuildConfig created? | Because no source build was needed |
Part 23: Full Validation Script
Run this after completing the lab:
oc project lab12-container-image
echo "Checking Deployment..."
oc get deployment parksmap
echo "Checking rollout..."
oc rollout status deployment/parksmap
echo "Checking pods..."
oc get pods -o wide
echo "Checking image..."
oc get deployment parksmap -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'
echo "Checking service..."
oc get svc parksmap
echo "Checking endpoints..."
oc get endpoints parksmap
echo "Checking route..."
oc get route parksmap
echo "Checking that no build exists..."
oc get bc
oc get builds
echo "Testing application route..."
APP_URL="http://$(oc get route parksmap -o jsonpath='{.spec.host}')"
echo "$APP_URL"
curl -I "$APP_URL"
Code language: PHP (php)
Expected result:
- Deployment is available.
- Pod is running.
- Service exists.
- Endpoint exists.
- Route exists.
- No BuildConfig exists.
- No Build exists.
- Browser URL works.
Part 24: Troubleshooting
Problem 1: ImagePullBackOff
Symptom
The pod is not running and shows:
ImagePullBackOff
or:
ErrImagePull
Check
Run:
oc get pods
Code language: JavaScript (javascript)
Describe the pod:
oc describe pod -l app=parksmap
If that selector does not work, run:
oc get pods --show-labels
Code language: JavaScript (javascript)
Then describe the pod by name:
oc describe pod <pod-name>
Code language: HTML, XML (xml)
Common Causes
- Wrong image name.
- Registry is temporarily unavailable.
- OpenShift Local cannot reach the registry.
- Image is private and needs a pull secret.
- VPN or firewall is blocking registry access.
Fix
Verify the image name:
quay.io/openshiftroadshow/parksmap:latest
Check CRC status:
crc status
If using VPN, disconnect VPN and retry if possible.
Restart the rollout:
oc rollout restart deployment/parksmap
Problem 2: Route Does Not Open
Symptom
The pod is running, but the browser page does not open.
Check
Run:
oc get route parksmap
Code language: JavaScript (javascript)
Check service:
oc get svc parksmap
Code language: JavaScript (javascript)
Check endpoints:
oc get endpoints parksmap
Code language: JavaScript (javascript)
If endpoints are empty, the Service is not pointing to the pod.
Check pod labels:
oc get pods --show-labels
Code language: JavaScript (javascript)
Check Service selector:
oc describe svc parksmap
The Service selector must match the pod labels.
Problem 3: Pod Is Running but App Is Not Responding
Check logs:
oc logs deployment/parksmap
Check pod status:
oc describe deployment parksmap
Check whether the Service has endpoints:
oc get endpoints parksmap
Code language: JavaScript (javascript)
If the application listens on a different port than the Service expects, the route may fail.
For this lab, the parksmap image is expected to expose the application through port 8080.
Problem 4: No Route Was Created
If you forgot to enable Create a route, create the Route manually:
oc expose svc/parksmap
Verify:
oc get route parksmap
Code language: JavaScript (javascript)
Open the route again.
Problem 5: BuildConfig Not Found
This is not an error.
This lab deploys an existing image.
So this output is expected:
oc get bc
Code language: JavaScript (javascript)
Expected:
No resources found
A BuildConfig is only needed when OpenShift builds an image from source code or binary input.
Problem 6: Application Works in Browser but curl Fails
Possible causes:
- Local DNS issue.
- Browser has a working DNS/proxy setup but terminal does not.
- VPN or firewall issue.
- CRC networking issue.
Check CRC:
crc status
Print the route:
oc get route parksmap
Code language: JavaScript (javascript)
Try again after a minute.
Part 25: Optional CLI-Only Equivalent
The main purpose of this lab is to use the web console.
However, the equivalent CLI workflow is useful to know.
Create a new project:
oc new-project lab12-container-image-cli
Code language: JavaScript (javascript)
Create the application from image:
oc new-app quay.io/openshiftroadshow/parksmap:latest --name=parksmap
Code language: JavaScript (javascript)
Expose the Service:
oc expose svc/parksmap
Check resources:
oc get deployment,pod,svc,route
Code language: JavaScript (javascript)
Test the route:
APP_URL="http://$(oc get route parksmap -o jsonpath='{.spec.host}')"
curl -I "$APP_URL"
Code language: JavaScript (javascript)
Clean up the CLI test project:
oc delete project lab12-container-image-cli
Code language: JavaScript (javascript)
Part 26: Cleanup
Cleanup from Web Console
- Go to the Developer perspective.
- Select project:
lab12-container-image
- Go to Topology.
- Open the action menu for the
parksmapapplication. - Click Delete Application.
- Confirm deletion.
This deletes the application resources.
Cleanup from CLI
The easiest cleanup is to delete the whole project:
oc delete project lab12-container-image
Code language: JavaScript (javascript)
Verify:
oc get project lab12-container-image
Code language: JavaScript (javascript)
Expected output:
Error from server (NotFound): projects.project.openshift.io "lab12-container-image" not found
Code language: JavaScript (javascript)
Part 27: Lab Summary
In this lab, you deployed an application from an existing container image using the OpenShift web console.
You learned that:
- Container images can be deployed directly without building source code.
- The Container images option is used when an image already exists in a registry.
- A Deployment runs the application.
- A Pod runs the actual container.
- A Service provides internal access.
- A Route provides external browser access.
- No BuildConfig or Build is created when deploying an existing image.
- OpenShift can scale and restart the application using Deployment features.
Part 28: Review Questions
Question 1
What was the input for this lab?
Answer
An existing container image:
quay.io/openshiftroadshow/parksmap:latest
Question 2
Did OpenShift build a new image in this lab?
Answer
No. OpenShift pulled and ran an existing image.
Question 3
Which OpenShift web-console option did we use?
Answer
+Add -> Container images
Question 4
Which resource runs the application?
Answer
Deployment.
Question 5
Which resource exposes the application inside the cluster?
Answer
Service.
Question 6
Which resource exposes the application outside the cluster?
Answer
Route.
Question 7
Why was no BuildConfig created?
Answer
Because OpenShift did not build source code. It deployed an image that already existed.
Question 8
What command checks the Deployment status?
Answer
oc rollout status deployment/parksmap
Question 9
What command shows the Route?
Answer
oc get route parksmap
Code language: JavaScript (javascript)
Question 10
What command deletes the full lab project?
Answer
oc delete project lab12-container-image
Code language: JavaScript (javascript)
Instructor Notes
This lab is designed as a replacement for the older short article about deploying an application from a container image.
The old articleโs topic is correct, but the replacement lab improves it by:
- Using OpenShift Local instead of Developer Sandbox.
- Using an official OpenShift sample image.
- Separating this lab from the Git/source-code workflow.
- Using Deployment instead of DeploymentConfig.
- Adding route, service, pod, and deployment validation.
- Explaining why no BuildConfig is created.
- Adding CLI checks.
- Adding troubleshooting.
- Adding cleanup steps.
For production or advanced courses, add follow-up labs for:
- Deploying images from a private registry.
- Creating image pull secrets.
- Deploying from an internal OpenShift ImageStream.
- Updating images by tag and digest.
- Using immutable image digests instead of
latest. - Image vulnerability scanning.
- Image signing and verification.
- GitOps-based image deployment.
- Rollback and rollout history.
- Resource requests and limits.
Instructor Pre-Validation Checklist
Before delivering this lab to students, run:
crc status
oc whoami
oc get nodes
Code language: JavaScript (javascript)
Create a quick test project:
oc new-project lab12-test
Code language: JavaScript (javascript)
Deploy the sample image:
oc new-app quay.io/openshiftroadshow/parksmap:latest --name=parksmap
Code language: JavaScript (javascript)
Expose it:
oc expose svc/parksmap
Validate:
oc rollout status deployment/parksmap
oc get pod,svc,route
APP_URL="http://$(oc get route parksmap -o jsonpath='{.spec.host}')"
curl -I "$APP_URL"
Code language: PHP (php)
Clean up:
oc delete project lab12-test
Code language: JavaScript (javascript)
If these commands pass, the lab is ready for students.
Final Outcome
You have successfully deployed an application from an existing container image using the OpenShift web console.
You now understand this workflow:
Container Image
-> Deployment
-> Pod
-> Service
-> Route
-> Browser
This is one of the most common real-world OpenShift workflows because many teams build images in CI/CD pipelines and then deploy those already-built images into OpenShift.
Iโm a DevOps/SRE/DevSecOps/Cloud Expert passionate about sharing knowledge and experiences. I have worked at Cotocus. I share tech blog at DevOps School, travel stories at Holiday Landmark, stock market tips at Stocks Mantra, health and fitness guidance at My Medic Plus, product reviews at TrueReviewNow , and SEO strategies at Wizbrand.
Do you want to learn Quantum Computing?
Please find my social handles as below;
Rajesh Kumar Personal Website
Rajesh Kumar at YOUTUBE
Rajesh Kumar at INSTAGRAM
Rajesh Kumar at X
Rajesh Kumar at FACEBOOK
Rajesh Kumar at LINKEDIN
Rajesh Kumar at WIZBRAND
Find Trusted Cardiac Hospitals
Compare heart hospitals by city and services โ all in one place.
Explore Hospitals
The article explains how to build and deploy applications from container images, but it could also cover image lifecycle management in production environments. As applications evolve, organizations need strategies for image versioning, vulnerability scanning, and automated rebuilds when base images receive security updates. Another valuable addition would be guidance on integrating image promotion workflows across development, staging, and production environments to ensure consistency, traceability, and compliance throughout the software delivery process.