# Build and deploy an application
In this example, you will see how to build an image from source code, and then store it in the registry and use that image when deploying an application in the cluster.
As a prerequisite, you should provide a route for the image registry as outlined in the section Exposing the image registry. You should also install a program that allows you to build images, for example, podman
or docker
. To install podman
on Fedora:
$ dnf install -y podman
For more information on podman
, see the RedHat article
Podman and Buildah for Docker users.
# Build the image
This example takes a simple NodeJS web application and builds an image using podman
. Download the sample from GitHub:
$ cd
$ git clone https://github.com/gabrielmcg/helloworld-nodejs
$ cd helloworld-nodejs
The program creates a trivial web server and responds with the message "Hello World" when a user accesses the home page.
The following excerpt from index.js
shows the primary components of the application:
const express = require("express");
const app = express();
app.get("/", (req, res) => {
console.log("Hello world received a request.");
const target = process.env.TARGET || "World";
res.send(`Hello ${target}!`);
});
const port = process.env.PORT || 8080;
app.listen(port, () => {
console.log("Hello world listening on port", port);
});
The accompanying Dockerfile
builds an image based on the official node:10
image, installs dependencies, copies in the source code and starts the webserver. You can use the podman
or docker
command, depending on your setup, to build the image.
$ podman build -t helloworld:v1 .
STEP 1: FROM node:10
STEP 2: WORKDIR /usr/src/app
9f57296b3b50125d693af6f559d671d3a577a5f3ba07f9dc752d229709411cbb
STEP 3: COPY package*.json ./
bd2ec027a14617a9cdbbadc9d3b8f3f55fd29611dda6e49d403e667d1ffe8c5e
STEP 4: RUN npm install --only=production
npm WARN helloworld-nodejs@1.0.0 No description
npm WARN helloworld-nodejs@1.0.0 No repository field.
added 48 packages from 36 contributors and audited 121 packages in 1.064s
found 0 vulnerabilities
153a13d7ff2f69fa76d82bb9561ffdbe09fe29b3ddf490f07efde963922c2daf
STEP 5: COPY . .
02a99699b19f7c1ae2cfa4ebf9653a15281d5fb757ab2c877fc287d5df812916
STEP 6: ENV PORT 8080
1b6e214c8f29a74124098c994ad9eb32ef970e1525c03dc7aa346e4dffda7ea7
STEP 7: CMD [ "npm", "start" ]
STEP 8: COMMIT helloworld:v1
3d05913e32f639e9d80f402e32c53be9471687b74fb5ff8e3c30353b0c835b41
Check that the image has been created locally:
$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/helloworld v1 3d05913e32f6 17 hours ago 935 MB
# Create the project
Create a new project named helloworld
:
$ oc new-project helloworld
Now using project "helloworld" on server "https://api.ocp.hpecloud.org:6443".
You can add applications to this project with the 'new-app' command. For example, try:
oc new-app django-psql-example
to build a new example application in Python. Or use kubectl to deploy a simple Kubernetes application:
kubectl create deployment hello-node --image=gcr.io/hello-minikube-zero-install/hello-node
# Tag and push the image
Tag the image before pushing to the local image registry, using the default route created earlier in the section Exposing the image registry:
$ podman tag helloworld:v1 default-route-openshift-image-registry.apps.ocp.hpecloud.org/helloworld/helloworld:v1
Log in to the local registry:
$ podman login -u kubeadmin -p $(oc whoami -t) default-route-openshift-image-registry.apps.ocp.hpecloud.org --tls-verify=false
Login Succeeded!
Push the image to the local registry:
$ podman push default-route-openshift-image-registry.apps.ocp.hpecloud.org/helloworld/helloworld:v1 --tls-verify=false
Getting image source signatures
Copying blob 553039093d83 done
Copying blob 73bfa217d66f done
Copying blob 91ecdd7165d3 done
Copying blob e4b20fcc48f4 done
Copying blob 5f3a5adb8e97 done
Copying blob 2e517d68c391 done
Copying blob 291f8a573386 done
Copying blob 10a2b00f2be1 done
Copying blob 86135eafe3c7 done
Copying blob 3d8956424ab7 done
Copying blob d51a74fa5b42 done
Copying blob 8186e77df3b5 done
Copying config 3d05913e32 done
Writing manifest to image destination
Copying config 3d05913e32 done
Writing manifest to image destination
Storing signatures
# Deploy the application
Deploy the application to the cluster:
$ kubectl create deployment helloworld --image=image-registry.openshift-image-registry.svc:5000/helloworld/helloworld:v1
deployment.apps/helloworld created
Wait for the application to be ready:
$ oc get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
helloworld 0/1 1 0 19s
$ oc get pods
NAME READY STATUS RESTARTS AGE
helloworld-d7f944d95-xlg88 0/1 ContainerCreating 0 24s
$ oc get pods
NAME READY STATUS RESTARTS AGE
helloworld-d7f944d95-xlg88 1/1 Running 0 38s
Check the logs for this pod to ensure that the appication started successfully:
$ oc logs helloworld-d7f944d95-xlg88
> helloworld-nodejs@1.0.0 start /usr/src/app
> node index.js
Hello world listening on port 8080
# Access the application
Create a service for the application:
$ oc expose deploy helloworld --port 8080
service/helloworld exposed
$ oc get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
helloworld ClusterIP 172.30.110.14 <none> 8080/TCP 5s
Test access to the service. First, establish a debug session on one of your nodes:
$ oc debug nodes/ocp-master1
Starting pod/ocp-master1-debug ...
To use host binaries, run `chroot /host`
Pod IP: 10.15.155.211
If you don't see a command prompt, try pressing enter.
sh-4.2#
Use the curl
command from the debug session to test access to the service from inside the cluster. You should see the message Hello World
displayed as a result of accessing the home page:
sh-4.2# curl 172.30.110.14:8080
Hello World!
sh-4.2# exit
# Access from outside the cluster
Create a route to provide access from outside the cluster:
$ oc expose svc/helloworld --name=helloworld
route.route.openshift.io/helloworld exposed
$ oc get route
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
helloworld helloworld-helloworld.apps.ocp.hpecloud.org helloworld 8080 None
You should now be able to access the application using this route from outside the cluster, for example, from your Ansible controller:
$ curl helloworld-helloworld.apps.ocp.hpecloud.org
Hello World!
# Known issue
Note: When you create the project, you are informed that you can use either oc new-app
or kubectl deploy
:
$ oc new-project helloworld
Now using project "helloworld" on server "https://api.ocp.hpecloud.org:6443".
You can add applications to this project with the 'new-app' command. For example, try:
oc new-app django-psql-example
to build a new example application in Python. Or use kubectl to deploy a simple Kubernetes application:
kubectl create deployment hello-node --image=gcr.io/hello-minikube-zero-install/hello-node
It is possible that if you use the oc new-app
option, you may enocunter an issue relating to certificates:
$ oc new-app default-route-openshift-image-registry.apps.ocp.hpecloud.org/helloworld/helloworld
W1205 11:08:19.556016 991 dockerimagelookup.go:236] container image registry lookup failed: Get https://default-route-openshift-image-registry.apps.ocp.hpecloud.org/v2/: x509: certificate signed by unknown authority
error: local file access failed with: stat default-route-openshift-image-registry.apps.ocp.hpecloud.org/helloworld/helloworld: no such file or directory
error: unable to locate any images in image streams, templates loaded in accessible projects, template files, local docker images with name "default-route-openshift-image-registry.apps.ocp.hpecloud.org/helloworld/helloworld"