Binary Deployments
OpenShift 3 offers a S2I (Source to Image) process to build applications where you can supply source code (your application source) and choose a builder image (a technology docker image such as JBoss EAP). S2I will build your application first and then layer your application on the top of the builder image to create an application docker image. This application docker image is then added to the repository and deployed as your application. This is all good for a complete DevOps model implemented by default within OpenShift.
Some of the OpenShift users want to build their application outside of OpenShift, perhaps using a build management tool that they already use, and use the resultant war file to deploy into OpenShift. We used to call this binary deployment in OpenShift v2 and I am using the same name here. This article discusses the approaches for binary deployment of the application war files that are built outside of OpenShift into the OpenShift 3 environment.
There are a few ways to deploy your war file into OpenShift 3 environment and you can choose whatever works best for your situation. OpenShift 3 being so very flexible, there may be additional ways to achieve this. I encourage the readers to list those in the comments as you discover more ways to do the same.
Note: I have packaged these examples and posted on github so that you can try them out. Hence, the tone of the rest of this blog is set like a tutorial or a lab exercise. In order to run these examples, you will need an OpenShift 3 environment and the OC CLI installed on your box. You should have connected to your OpenShift 3 environment using oc login. You can change the hostnames based on the specifics of your setup.
Docker Build Method
As the first approach we will discuss the docker build method. In this process we won't use S2I but instead use a docker file to deploy a .war file into OpenShift. Let us look at the example below.
Here I am deploying a previously created petstore.war
file. I have a git repository for my application that only has a Dockerfile with the following contents:
FROM registry.access.redhat.com/jboss-eap-6/eap-openshift:6.4
EXPOSE 8080 8888
RUN curl https://raw.githubusercontent.com/VeerMuchandi/ps/master/deployments/ROOT.war -o $JBOSS_HOME/standalone/deployments/ROOT.war
All this does is use the jboss-eap-6
image provided by OpenShift and add my .war file to the /deployments/
folder. When you create an application using this Dockerfile, OpenShift invokes a docker build to create your application image and deploy it. Lets look at the steps:
Step 1: Let us start by creating a new project. I am naming it petstore.
<code>$ oc new-project petstore</code>
Step 2: Create a new application within that project using the Dockerfile. You will see below that I am pointing to my git repository while creating the application. Since my repository contains a Dockerfile, OpenShift understands that it has to do a Docker Build. I am naming my application petstore again here.
$ oc new-app https://github.com/VeerMuchandi/dockrbld-bin-dep.git --name=petstore
imagestreams/petstore
buildconfigs/petstore
deploymentconfigs/petstore
services/petstore
A build was created - you can run `oc start-build petstore` to start it.
Service "petstore" created at 172.30.10.221 with port mappings 8080->8080, 8888->8888.
You will notice that the above step also created a service with the name petstore
.
If you get a warning message in the above step such as the one shown below, you can ignore it.
<code>Could not find an image match for "registry.access.redhat.com/jboss-eap-6/eap-openshift:6.4". Make sure that a Docker image with that tag is available on the OpenShift node for the build to succeed.</code>
Step 3: Now let's add a route that exposes this service with the url petstore.testv3.osecloud.com:
$ oc expose service petstore --hostname=petstore.testv3.osecloud.com
NAME HOST/PORT PATH SERVICE LABELS
petstore petstore.testv3.osecloud.com petstore
Step 4: Next we will start a build by issuing a start-build command as shown below. It also displays the name assigned to the running build.
$ oc start-build petstore
petstore-1
You can watch the build logs as the build is in progress. You will notice that OpenShift runs what we listed in the Dockerfile. It gets the builder image for jboss-eap-6
from registry, downloads the .war file and adds it to the $JBOSS_HOME/standalone/deployments
folder. It then creates a new application image and pushes into the docker registry configured in OpenShift.
$ oc build-logs petstore-1
I0710 16:53:55.480823 1 cfg.go:50] Problem accessing /root/.dockercfg: stat /root/.dockercfg: no such file or directory
I0710 16:53:57.621261 1 docker.go:69] Starting Docker build from petstore/petstore-1 BuildConfig ...
I0710 16:53:57.625443 1 tar.go:133] Adding to tar: /tmp/docker-build051447222/Dockerfile as Dockerfile
Step 0 : FROM registry.access.redhat.com/jboss-eap-6/eap-openshift:6.4
---> 85765d60ad46
Step 1 : EXPOSE 8080 8888
---> Running in 41ca38853cfb
---> 113b97247c5d
Removing intermediate container 41ca38853cfb
Step 2 : RUN curl https://raw.githubusercontent.com/VeerMuchandi/ps/master/deployments/ROOT.war -o $JBOSS_HOME/standalone/deployments/ROOT.war
---> Running in f0424ebe8bb6
% Total % Received % Xferd Average Speed Time Time Time Current
>Dload Upload Total Spent Left Speed
100 6011k 100 6011k 0 0 307k 0 0:00:19 0:00:19 --:--:-- 1459k
---> 63908bcc750f
Removing intermediate container f0424ebe8bb6
Step 3 : ENV OPENSHIFT_BUILD_NAME "petstore-1" OPENSHIFT_BUILD_NAMESPACE "petstore" OPENSHIFT_BUILD_SOURCE "https://github.com/VeerMuchandi/dockrbld-bin-dep.git"
---> Running in c16f2fc92da8
---> 292ebddba482
Removing intermediate container c16f2fc92da8
Successfully built 292ebddba482
I0710 16:54:51.511380 1 cfg.go:46]
PUSH_DOCKERCFG_PATH=/var/run/secrets/openshift.io/push/.dockercfg
I0710 16:54:51.511826 1 cfg.go:64] Using serviceaccount user for Docker authentication
I0710 16:54:51.511847 1 docker.go:84] Using Docker authentication provided
I0710 16:54:51.511862 1 docker.go:87] Pushing 172.30.246.7:5000/petstore/petstore image ...
I0710 16:55:14.031293 1 docker.go:91] Successfully pushed 172.30.246.7:5000/petstore/petstore
Step 5: Once the build is successful, you'll notice that OpenShift deploys the application as a pod and your pod starts running. You can see that the build pod is complete with ExitCode
of 0
and the application pod is running.
$ oc get pods
NAME READY REASON RESTARTS AGE
petstore-1-build 0/1 ExitCode:0 0 7m
petstore-1-mtc63 1/1 Running 0 51s
You can watch the logs for your pod with the command oc logs petstore-1-mtc63
if you wish to. You can see that the ROOT.war
gets deployed.
Step 6: Now if you type in your url in the browser your favorite petstore app will be shown. You can initialize the database and using petstore if you want to try it out!
S2I with Customized Assemble Script
The Source to Image process uses the assemble STI script that builds the application artifacts from a source and places them into appropriate directories inside the image. We can customize this assemble script if we need to. The approach in this section uses a small change to this assemble script to deploy our .war file.
Here are two such customized assemble scripts for jbosseap and jbossews:
https://github.com/VeerMuchandi/eap6-bin-deploy
https://github.com/VeerMuchandi/ews-bin-deploy
As we are deploying only a .war file and not any code, there is no need to add any code here. You will notice that we have a .sti/bin directory
in each repository and an assemble script posted in there. I just added one step to this script to copy the .war file to the deployments folder.
<code>curl -o <span class="pl-smi">${DEPLOY_DIR}</span>/ROOT.war -O <span class="pl-smi">${WAR_FILE_URL}</span></code>
It is as simple as that. This script uses an environment variable to pass the .war file url. So you can deploy your own warfile using this script instead of what we are testing in the steps below. Now let us try to use this script to deploy our favorite petstore .war file.
Step 1: Let us first clean up our petstore project created earlier. If you are directly jumping to this approach create a new project instead.
<code>$ oc project petstore</code>
This will change you to use petstore project.
<code>$ oc delete all --all</code>
This will delete everything in the project.
Step 2: Create the application.
This time we will use JBossEWS. We are asking it to use jboss-webserver3-tomcat8-openshift
builder image and pointing to the git repository that has the custom assemble script for jbossews. Let us name this application petstore again.
$ oc new-app jboss-webserver3-tomcat8-openshift~https://github.com/VeerMuchandi/ews-bin-deploy.git --name=petstore
imagestreams/petstore
buildconfigs/petstore
deploymentconfigs/petstore
services/petstore
A build was created - you can run `oc start-build petstore` to start it.
Service "petstore" created at 172.30.76.144 with port mappings 8080->8080, 8443->8443.
Note: You can follow the same steps to do binary deployment using the JBossEAP image in which case you would use https://github.com/VeerMuchandi/eap6-bin-deploy.git
as the GitURL.
Step 3: Let us add a route to this application just like before with the URL petstore.testv3.osecloud.com:
$ oc expose service petstore --hostname=petstore.testv3.osecloud.com
NAME HOST/PORT PATH SERVICE LABELS
petstore petstore.testv3.osecloud.com petstore
Step 4: Edit Build Configuration.
In the custom assemble script we passed an environment variable. But we did not assign any value to that yet. We need to tell our build configuration on which .war file to use to deploy. Now we will edit the build configuration to add an environment variable WAR_FILE_URL
that points to where your .war file is. Your build management tool may have placed your .war file in an artifact repository and you can point to that. In this example, we are using the petstore war file that I posted on github.
Note: OpenShift does an automatic build and deploy within minutes after your application is created. So by the time you are here, a build may have already started. Don't worry. There is no harm. Let it go. We will start a build again after we edited the build configuration.
Run the following command to get your build configuration:
$ oc get bc
NAME TYPE SOURCE
petstore Source https://github.com/VeerMuchandi/ews-bin-deploy.git
Now let us edit the build configuration using oc edit
. I prefer editing it as json as I don't have to worry about the number of spaces in a yaml.
<code>$ oc edit bc -o json</code>
This will open up your build configuration. Use it as a 'vi' editor, find the sourceStrategy
section and add the environment variable. Your sourceStrategy
section should look as shown below. Here you can replace the .war file URL with your own if you want to deploy your application instead of petstore.
Note: Be careful about closing the braces and don't forget to add a comma at the end of the from section.
"sourceStrategy": {
"from": {
"kind": "ImageStreamTag",
"namespace": "openshift",
"name": "jboss-webserver3-tomcat8-openshift:latest"
},
"env": [
{
"name": "WAR_FILE_URL",
"value": "https://raw.githubusercontent.com/VeerMuchandi/ps/master/deployments/ROOT.war"
}
]
}
You can save and exit from the editor.
Step 5: Once the build configuration is changed start a new build. As said before, a build may have already run once. Ignore that.
$ oc start-build petstore
petstore-2
You can watch the build logs just like before. You will notice that the S2I build process uses the custom assemble script to download the tomcat builder image, it downloads the .war file, builds an application image by layering it on the top of tomcat builder image and pushes it into the registry.
$ oc build-logs petstore-2
I0729 10:28:00.649417 1 cfg.go:50] Problem accessing /root/.dockercfg: stat /root/.dockercfg: no such file or directory
I0729 10:28:00.659164 1 sti.go:77] Creating a new S2I builder with build config: "Builder Image:\t\tregistry.access.redhat.com/jboss-webserver-3/tomcat8-openshift:3.0-137\nSource:\t\t\thttps://github.com/VeerMuchandi/ews-bin-deploy.git\nOutput Image Tag:\t172.30.162.74:5000/petstore/petstore\nEnvironment:\t\tOPENSHIFT_BUILD_SOURCE=https://github.com/VeerMuchandi/ews-bin-deploy.git,WAR_FILE_URL=https://raw.githubusercontent.com/VeerMuchandi/ps/master/deployments/ROOT.war,OPENSHIFT_BUILD_NAME=petstore-2,OPENSHIFT_BUILD_NAMESPACE=petstore\nIncremental Build:\tdisabled\nRemove Old Build:\tdisabled\nForce Pull:\t\tdisabled\nQuiet:\t\t\tdisabled\nLayered Build:\t\tdisabled\nDocker Endpoint:\tunix:///var/run/docker.sock\n"
I0729 10:28:00.667657 1 docker.go:187] Pulling image registry.access.redhat.com/jboss-webserver-3/tomcat8-openshift:3.0-137
I0729 10:28:31.555155 1 sti.go:83] Starting S2I build from petstore/petstore-2 BuildConfig ...
I0729 10:28:31.555267 1 sti.go:112] Building 172.30.162.74:5000/petstore/petstore
I0729 10:28:31.754121 1 clone.go:26] Cloning into /tmp/sti046720555/upload/src
I0729 10:28:34.213739 1 docker.go:180] Image registry.access.redhat.com/jboss-webserver-3/tomcat8-openshift:3.0-137 available locally
I0729 10:28:34.213862 1 docker.go:267] Image contains io.s2i.scripts-url set to 'image:///usr/local/sti'
I0729 10:28:34.213982 1 download.go:56] Using image internal scripts from: image:///usr/local/sti/assemble
I0729 10:28:34.214024 1 download.go:56] Using image internal scripts from: image:///usr/local/sti/run
I0729 10:28:34.218809 1 docker.go:180] Image registry.access.redhat.com/jboss-webserver-3/tomcat8-openshift:3.0-137 available locally
I0729 10:28:34.218875 1 docker.go:267] Image contains io.s2i.scripts-url set to 'image:///usr/local/sti'
I0729 10:28:34.218994 1 download.go:56] Using image internal scripts from: image:///usr/local/sti/save-artifacts
I0729 10:28:34.219036 1 sti.go:182] Using assemble from upload/src/.sti/bin
I0729 10:28:34.219067 1 sti.go:182] Using run from image:///usr/local/sti
I0729 10:28:34.219103 1 sti.go:182] Using save-artifacts from image:///usr/local/sti
I0729 10:28:34.219148 1 sti.go:120] Clean build will be performed
I0729 10:28:34.219174 1 sti.go:123] Performing source build from https://github.com/VeerMuchandi/ews-bin-deploy.git
I0729 10:28:34.219198 1 sti.go:130] Building 172.30.162.74:5000/petstore/petstore
I0729 10:28:34.219226 1 sti.go:326] Using image name registry.access.redhat.com/jboss-webserver-3/tomcat8-openshift:3.0-137
I0729 10:28:34.219279 1 sti.go:330] No .sti/environment provided (no evironment file found in application sources)
I0729 10:28:34.219896 1 tar.go:133] Adding to tar: /tmp/sti046720555/upload/scripts/assemble as scripts/assemble
I0729 10:28:34.235592 1 docker.go:315] Both scripts and untarred source will be placed in '/tmp'
I0729 10:28:34.235682 1 docker.go:350] Creating container using config: {Hostname: Domainname: User: Memory:0 MemorySwap:0 CPUShares:0 CPUSet: AttachStdin:false AttachStdout:true AttachStderr:false PortSpecs:[] ExposedPorts:map[] Tty:false OpenStdin:true StdinOnce:true Env:[OPENSHIFT_BUILD_NAME=petstore-2 OPENSHIFT_BUILD_NAMESPACE=petstore OPENSHIFT_BUILD_SOURCE=https://github.com/VeerMuchandi/ews-bin-deploy.git WAR_FILE_URL=https://raw.githubusercontent.com/VeerMuchandi/ps/master/deployments/ROOT.war] Cmd:[/bin/sh -c tar -C /tmp -xf - && /tmp/scripts/assemble] DNS:[] Image:registry.access.redhat.com/jboss-webserver-3/tomcat8-openshift:3.0-137 Volumes:map[] VolumesFrom: WorkingDir: MacAddress: Entrypoint:[] NetworkDisabled:false SecurityOpts:[] OnBuild:[] Labels:map[]}
I0729 10:28:35.592048 1 docker.go:357] Attaching to container
I0729 10:28:35.604127 1 docker.go:414] Starting container
I0729 10:28:36.094139 1 docker.go:424] Waiting for container
E0729 10:28:36.437997 1 sti.go:414] cp: cannot stat '/tmp/src/*': No such file or directory
E0729 10:28:36.438208 1 sti.go:414] cp: cannot stat '/tmp/src/*': No such file or directory
I0729 10:28:36.440131 1 sti.go:388] Veer - Custom code for binary deployment
I0729 10:28:36.440239 1 sti.go:388] https://raw.githubusercontent.com/VeerMuchandi/ps/master/deployments/ROOT.war
E0729 10:28:36.679885 1 sti.go:414] % Total % Received % Xferd Average Speed Time Time Time Current
E0729 10:28:36.680047 1 sti.go:414] Dload Upload Total Spent Left Speed
% Total % Received % Xferd A0 0 0 0 0 verage Speed Time Time Time Current
E0729 10:28:36.680188 1 sti.go:414] Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 00 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 6011k 100 6011k 0 0 3182k 0 0:00:01 0:00:01 --:--:-- 3182k
E0729 10:28:38.567714 1 sti.go:414] 0 3182k 0 0:00:01 0:00:01 --:--:-- 3182k
I0729 10:28:38.866795 1 docker.go:430] Container exited
I0729 10:28:38.866859 1 docker.go:436] Invoking postExecution function
I0729 10:28:38.866919 1 sti.go:216] No .sti/environment provided (no evironment file found in application sources)
I0729 10:28:38.867063 1 docker.go:469] Committing container with config: {Hostname: Domainname: User: Memory:0 MemorySwap:0 CPUShares:0 CPUSet: AttachStdin:false AttachStdout:false AttachStderr:false PortSpecs:[] ExposedPorts:map[] Tty:false OpenStdin:false StdinOnce:false Env:[OPENSHIFT_BUILD_NAME=petstore-2 OPENSHIFT_BUILD_NAMESPACE=petstore OPENSHIFT_BUILD_SOURCE=https://github.com/VeerMuchandi/ews-bin-deploy.git WAR_FILE_URL=https://raw.githubusercontent.com/VeerMuchandi/ps/master/deployments/ROOT.war] Cmd:[/usr/local/sti/run] DNS:[] Image: Volumes:map[] VolumesFrom: WorkingDir: MacAddress: Entrypoint:[] NetworkDisabled:false SecurityOpts:[] OnBuild:[] Labels:map[]}
I0729 10:28:49.529515 1 sti.go:246] Successfully built 172.30.162.74:5000/petstore/petstore
I0729 10:28:49.613093 1 cleanup.go:23] Removing temporary directory /tmp/sti046720555
I0729 10:28:49.613147 1 fs.go:99] Removing directory '/tmp/sti046720555'
I0729 10:28:49.616846 1 cfg.go:46] PUSH_DOCKERCFG_PATH=/var/run/secrets/openshift.io/push/.dockercfg
I0729 10:28:49.617207 1 cfg.go:64] Using serviceaccount user for Docker authentication
I0729 10:28:49.617250 1 sti.go:131] Using provided push secret for pushing 172.30.162.74:5000/petstore/petstore image
I0729 10:28:49.617266 1 sti.go:134] Pushing 172.30.162.74:5000/petstore/petstore image ...
I0729 10:30:39.375996 1 sti.go:138] Successfully pushed 172.30.162.74:5000/petstore/petstore
Step 6: Right after the build is complete, OpenShift initiates the deploy process and you will see the application running. If you get the list of pods you will note the application pod running.
$ oc get pods
NAME READY REASON RESTARTS AGE
petstore-1-build 0/1 ExitCode:0 0 14m
petstore-2-build 0/1 ExitCode:0 0 7m
petstore-2-uxh4v 1/1 Running 0 4m
Step 7: Now if you try the url for the application in the browser and petstore comes up.
Other Options
There are a couple of other options that you may choose based on your preference, such as
- You can build a docker image for your application completely outside of OpenShift and deploy it in OpenShift. In such a case OpenShift does handle the build at all; it just runs your application docker image.
- Include your .war file in a `pom.xml` that pulls the .war file and places in the deployments folder. In this case, you will need to create a git repository that holds the `pom.xml` and use that repository to create your application in openshift using `oc new-app`. I contemplated that angle, and ended up using the above custom assemble script approach as the custom assemble script that we saw above can be used with any .war file.
Summary
In this article we have seen two ways to deploy your .war file into OpenShift. Other options are also possible.
À propos de l'auteur
Parcourir par canal
Automatisation
Les dernières nouveautés en matière d'automatisation informatique pour les technologies, les équipes et les environnements
Intelligence artificielle
Actualité sur les plateformes qui permettent aux clients d'exécuter des charges de travail d'IA sur tout type d'environnement
Cloud hybride ouvert
Découvrez comment créer un avenir flexible grâce au cloud hybride
Sécurité
Les dernières actualités sur la façon dont nous réduisons les risques dans tous les environnements et technologies
Edge computing
Actualité sur les plateformes qui simplifient les opérations en périphérie
Infrastructure
Les dernières nouveautés sur la plateforme Linux d'entreprise leader au monde
Applications
À l’intérieur de nos solutions aux défis d’application les plus difficiles
Programmes originaux
Histoires passionnantes de créateurs et de leaders de technologies d'entreprise
Produits
- Red Hat Enterprise Linux
- Red Hat OpenShift
- Red Hat Ansible Automation Platform
- Services cloud
- Voir tous les produits
Outils
- Formation et certification
- Mon compte
- Assistance client
- Ressources développeurs
- Rechercher un partenaire
- Red Hat Ecosystem Catalog
- Calculateur de valeur Red Hat
- Documentation
Essayer, acheter et vendre
Communication
- Contacter le service commercial
- Contactez notre service clientèle
- Contacter le service de formation
- Réseaux sociaux
À propos de Red Hat
Premier éditeur mondial de solutions Open Source pour les entreprises, nous fournissons des technologies Linux, cloud, de conteneurs et Kubernetes. Nous proposons des solutions stables qui aident les entreprises à jongler avec les divers environnements et plateformes, du cœur du datacenter à la périphérie du réseau.
Sélectionner une langue
Red Hat legal and privacy links
- À propos de Red Hat
- Carrières
- Événements
- Bureaux
- Contacter Red Hat
- Lire le blog Red Hat
- Diversité, équité et inclusion
- Cool Stuff Store
- Red Hat Summit