Enterprise grade Java.
You'll read about Conferences, Java User Groups, Java, Integration, Reactive, Microservices and other technologies.

Wednesday, November 4, 2015

Promoting Docker Images Across Environments

16:00 Wednesday, November 4, 2015 Posted by Markus Eisele
, , ,
I got off the stage at WJAX in Munch just a couple of minutes ago. And while my co-worker Jan was talking about this amazing customer success story AMADEUS, I had the pleasure to base his thoughts and ideas a bit and talk about how DevOps can be done with OpenShift and Docker Images from a developers perspective.

Microservices and DevOps
If you have hundreds or even more container running in production everything isn't any longer just an operations problem. Not only because everybody is part of the DevOps movement today, but mainly, because we have to build our applications differently if we want to be able to profit from the synergies provided by immutable and stateless containers. The example I was using in the keynote was pretty much the same, that has been used on my blog before. A single WidlFly Swarm JAX-RS service, which does little more than printing out some JSON which contains an environment variable and a timestamp. The thing, that the series was missing is the staging across environments. And while there are some great blogs by Veer Muchandi over at OpenShift, they all assume that you use the OpenShift way of building images and applications.

Let's Stick To Plain Docker
I wanted to show, how easy it is while using plain Docker Images. So, assuming that you have a very straight forward environment setup:
Environment Setup (Dev, QA, Production)
We have a dev environment which the developers use to just push their updated images. And another QA environment where the testers go crazy and probably many others. The example I showed just used the two mentioned. It will be pretty much the same for every other env you add. Let's see how this works with Maven, Docker and OpenShift

I used the fabric8 vagrant image in this case behind the scenes. Only because they always pull in the latest OpenShift builds and I wanted to show the new visualizations that are already in HEAD. So, install vagrant and the OpenShift binaries and fire up the openshift vagrant machine. I tweaked the memory and cpu settings a bit to 8 GB and 4 cores. Make sure to expose the internal Docker Registry as shown in the earlier blogpost. If you set your DOCKER_HOST variable accordingly you can start the walk-through. The recording of the demo gives you the complete show in about 10 minutes. And yes, there's no audio in this one.

The Individual Steps
Sometimes it is easier to just follow the individual steps yourself. Here they are:
Login to OpenShift as admin with password admin
oc login https://vagrant.f8:8443 --insecure-skip-tls-verify=true

Build your Maven based project (maybe just git clone my example and use that)
mvn clean install

Run the Local WildFly Swarm fat-jar
java -jar target/swarm-sample-0.0.1-SNAPSHOT-swarm.jar

Point your browser to http://localhost:8080/api/v1/service and verify everything is working as expected

Before you build the Docker Image from your application, make sure to pull the jboss/base-jdk:8 image. I don't know exactly why, but the plugin seems to have an issue with resolving it.
docker pull jboss/base-jdk:8 

Now build your Docker image
mvn clean install docker:build 

Look at the resulting Dockerfile
cat target/docker/development/swarm-sample/latest/build/Dockerfile

Create a new development project in OpenShift. At this point it doesn't matter, if it is a project in the same instance or another environment. As I was going to demo this locally on my laptop, the decision was easy. Compare Veers post from above, if you want to learn how to stage across physical environments.
oc new-project development --display-name="WildFly Swarm Development Project"

Add rights to view and edit for both users dev1 and test1
oc policy add-role-to-user edit dev1
oc policy add-role-to-user view test1

Create a QA project in OpenShift
oc new-project test --display-name="WildFly Swarm QA Project"

Give the test1 user the edit rights:
oc policy add-role-to-user edit test1

Add roles to system accounts to be able to pull images from QA out of the development environment
 oc policy add-role-to-group system:image-puller system:serviceaccounts:test -n development

Login as dev1 with password dev1 and get your access token
oc login https://vagrant.f8:8443 -u dev1
oc whoami -t

Change the token in the authConfig section of your pom.xml. Now, you're ready to push your WildFly Swarm Docker Image to the OpenShift Docker registry
mvn docker:push

Create an app from the image
oc new-app --docker-image=development/swarm-sample:latest

Expose a route for the newly created route. And make sure to have your hosts file updated with the correct mappings before accessing it via your browser.
oc expose service swarm-sample --hostname=wildfly-swarm.vagrant.f8

Check http://wildfly-swarm.vagrant.f8/api/v1/service and see, if everything works.

Get the OpenShift image streams from the image
oc get is
oc describe is 

Tag a new image from latest to promote
oc tag development/swarm-sample:promote

Login as user test1 with password test1 and switch to the test project
oc login -u test1
oc project test

Create an application from the promoted image
oc new-app development/swarm-sample:promote

Expose the service as a route
oc expose service swarm-sample --hostname=wildfly-swarm-test.vagrant.f8

Check, if you can access: http://wildfly-swarm-test.vagrant.f8/api/v1/service

If you now login as dev1 again, go full development cycle and change the app, build a new image and push it again, you can see, that only the development environment gets updated, while the QA environment still stays on the promoted tag. When developers feel like updating QA again, you can just promote the "new" latest version of the image and the test environment will get updated, too.