OpenShift Build and Deploy a JEE Application with S2I
External
- https://blog.openshift.com/getting-java-ee-code-running-docker-containers-openshift/
- https://blog.openshift.com/improving-build-time-java-builds-openshift/
Internal
Overview
This article describes the process of setting up a project that builds from sources and deploys a simple JEE application. The source of the application is exposed in GitHub. We will use https://github.com/NovaOrdis/novaordis-session-servlet (Session Servlet Example). The final artifact will be deployed in a EAP 7 instance.
Create the OpenShift Project
The application will be hosted in its own OpenShift project:
oc new-project s2i-build-example \ --display-name='S2I Build Example' \ --description='A JEE Application that builds from source and deploys onto a EAP 7 instance'
Identify the Application Template
Since we intend to deploy our JEE application in top of a JEE container, the simplest method is to identify the application template that matches our requirements and use it. OpenShift comes with a series of application templates, which are pre-loaded in the "openshift" project:
oc get templates -n openshift
The application template that matches our requirements is "eap70-basic-s2i"
It can be explored with:
oc get -o yaml template eap70-basic-s2i -n open shift
The template can be used "as-is", or it can be downloaded locally and modified - for example, we can change the labels applied by the template to the objects it creates, so instead of "app=eap70-basic-s2i", we can use a more custom name for our application. Some of the parameters, including the application name, are allowed to be changed on command line. It is a good idea to review the application template and identify all parameters that can be customized.
Create the Application
oc new-app eap70-basic-s2i \ --param APPLICATION_NAME=<application-name> \ --param HOSTNAME_HTTP=<custom-hostname-instead-of-application_name.project.default_routing_subdomain> \ --param SOURCE_REPOSITORY_URL=<git-repository-url> \ --param SOURCE_REPOSITORY_REF=<git-branch/tag-reference> \ --param CONTEXT_DIR=<path-withing-git-project-to-build> \ --param GITHUB_WEBHOOK_SECRET=<github-webhook-secret> \ --param IMAGE_STREAM_NAMESPACE=<imagestream-namespace> \ --param MAVEN_MIRROR_URL=<maven-mirror-to-use-for-S2I-builds>
Example:
oc new-app eap70-basic-s2i \ --param APPLICATION_NAME=session-servlet \ --param HOSTNAME_HTTP=session-servlet.apps.openshift.novaordis.io \ --param SOURCE_REPOSITORY_URL=https://github.com/NovaOrdis/novaordis-session-servlet.git \ --param SOURCE_REPOSITORY_REF=master \ --param CONTEXT_DIR=/ \ --param GITHUB_WEBHOOK_SECRET=n2h6dtHw7Gw3 \ --param IMAGE_STREAM_NAMESPACE=openshift
Once executed, the "new-app" command creates the following:
- a "session-servlet" service
- a route that exposes the service as "http://session-servlet.apps.openshift.novaordis.io"
- a project-scoped image stream
- a build configuration
- a deployment configuration
Build
The build process starts immediately and its logs can be monitored with:
oc logs -f build/session-servlet-1
If successful, the build results in the creation of a new deployable image that gets uploaded into the integrated docker registry:
oc get is
NAME DOCKER REPO TAGS UPDATED session-servlet docker-registry.default.svc:5000/s2i-build-example/session-servlet latest 5 minutes ago
How do I build new images and how do I control the tag?
Process
"Join" Projects
If the source repository pod runs in a collocated OpenShift project, and we want to use the internal DNS name, we need to join the projects.
oadm pod-network join-projects --to=cicd lab
oc new-app <openshift-project-template-name> \ --param APPLICATION_NAME=<application-name> \ --param SOURCE_REPOSITORY_URL=<git-url> \ --param SOURCE_REPOSITORY_REF=master \ --param CONTEXT_DIR=/
oc new-app eap64-basic-s2i \ --param APPLICATION_NAME=tasks \ --param SOURCE_REPOSITORY_URL=http://gogs.cicd.svc.cluster.local:3000/gogs/openshift-tasks-private \ --param SOURCE_REPOSITORY_REF=master \ --param CONTEXT_DIR=/
This command uses openshift project's "eap64-basic-s2i" template and creates:
- a build configuration
- an image stream
- a deployment configuration
- a route
- a service
--> Deploying template "openshift/eap64-basic-s2i" to project lab Red Hat JBoss EAP 6.4 (no https) --------- Application template for EAP 6 applications built using S2I. A new EAP 6 based application has been created in your project. * With parameters: * Application Name=tasks * Custom http Route Hostname= * Git Repository URL=https://gogs.cicd.svc.cluster.local:3000/gogs/openshift-tasks-private * Git Reference=master * Context Directory=/ * Queues= * Topics= * HornetQ Password=VvEf5H0S # generated * Github Webhook Secret=8Xk5LAnr # generated * Generic Webhook Secret=mn5K7NNA # generated * ImageStream Namespace=openshift * JGroups Cluster Password=r1Elwibf # generated * Deploy Exploded Archives=false * Maven mirror URL= * ARTIFACT_DIR= --> Creating resources ... service "tasks" created route "tasks" created imagestream "tasks" created buildconfig "tasks" created deploymentconfig "tasks" created --> Success Build scheduled, use 'oc logs -f bc/tasks' to track its progress. Run 'oc status' to view your app.
Because the Git repository is private and protected by username/password, the initial build attempt will fail:
oc logs -f build/tasks-1 ... error: build error: failed to fetch requested repository "http://gogs.cicd.svc.cluster.local:3000/gogs/openshift-tasks-private" with provided credentials
Add Source Repository Secrets
If the source repository is protected, we need to place credentials into the builder configuration, and the builder service account environment:
oc secrets new-basicauth gogs-basicauth --username=gogs --password=... oc secrets link builder gogs-basicauth oc set build-secret --source bc/tasks gogs-basicauth
Restart the Build
oc start-build tasks