Migrating to Kubernetes With OpenShift

Multi-cloud solutions are increasingly becoming a key component of a digital transformation initiative because of the flexibility and options available. However, I find the key element is finding the right strategy. OpenShift is one of the strategies available when it comes to your cloud-native application, so let’s look at what it can do, and what challenges can occur.

There are far too many advocates of DevOps & Cloud saying, “{insert any modern tech} is easy, why aren’t you using it yet?”. To be honest, I can be guilty of that sometimes. When you’ve been working with the HashiCorp suite of tools, automation tools such as Ansible, Puppet & Chef, and a whole other bunch of tech stacks for monitoring and provisioning, it’s easy to forget that some people don’t even know what Ansible is, what containers are, or what Terraform does.

I’ve been working with UKCloud for the last 18 months to help their clients adapt to some of the DevOps ways of working; mostly from an automation and up-skilling point of view, but also with cultural collaboration where appropriate. Helping transform from old, legacy applications, into cloud-native services has been a great experience. Seeing first-hand the great service UKCloud offer with regards to a secure trusted domain, especially with health data is amazing.


Of the technologies I’ve been particularly grateful to have been working with, is OpenShift. Given that the majority of its developers are also core Kubernetes developers really does give it the edge over other Kubernetes tools. For those that are unaware, OpenShift is a product from RedHat, and is essentially a wrapper around Kubernetes with a LOT of extra features. Arguably one of its best features it the “Source to Image” builder (s2i), which allows a developer to give OpenShift their GitHub URL, and it will be deployed within a matter of seconds on a relevant container, deployed with Kubernetes.

Service routes allow projects to be A/B tested with ease, whilst build triggers allow seamless continuous deployment opportunities, especially when coupled with the Jenkins Pipeline plugin. “Build Secrets” and “Source Secrets” forces security from the get go, and running anything as root is forbidden.

Simple. Secure. Fast.

So why the post?

I particularly wanted to write this post, because after working with a number of clients, I’ve come across a common problem which I alluded to in my first paragraph of this post. OpenShift is amazing, but due to the nature of the technology it’s still further ahead than some of the people trying to use it. Yes, there are workarounds, but that tends to make more complex solutions, whereas less-experienced Devs/DevOps need less complex solutions!

Common Problem

Without naming the clients (there’s multiple), it’s quite common that there is a PHP application with a composon.json file. In the same directory, there is also a packages.json (for NPM), and sometimes there is also a Gruntfile / RakeFile / MakeFile / GulpFile / bower.json, etc. So many different packaging/dependency tools. It’s rather normal for an app to look like this unless you’ve already gone through the stages of breaking down your app into micro-services, which most of these clients haven’t done yet.

One of the great things about the Source2Image builder is its ability to detect the type of service that you are deploying, and use the correct builder-image to do that.

Therein, lies the start of the problem. If I were to deploy a PHP image using solely my GitHub URL pointing to my PHP image, OpenShift would detect the code is PHP, grab the default PHP S2I image and execute the following code snippet:


if [ -f composer.json ]; then

  echo “Found ‘composer.json’, installing dependencies using composer.phar… “




That’s awesome if all your app does is install a PHP micro-service. What about any frontend stuff? Npm? Gulp Yarn/Bower?

I totally understand the obvious answer is to build a custom Dockerfile and use that in OpenShift instead, but that would add a whole bunch of extra effort. The people I am showing OpenShift to may not have even used Docker yet. They just need to deploy their natively cloud-friendly application in a scalable, persistent manor, and would like to use the power of S2I within OpenShift as easily as possible.

It would of course be very easy to use constructive criticism and say, “well, you need to change your app because you need 1 service here and another here, here and here”, and “your frontend should actually just be using a JavaScript framework to communicate over RESTful API using JSON Web Tokens for authentication so you can have a standalone ‘frontend app’ and have a dedicated API that communicates to other services using protocol buffers…”.

But then all you’ve done there is add another couple of months work to a Developers pipeline, when they thought it was ready to deploy in OpenShift, which being less pedantic, it is.


I can imagine the same people that would stick to their guns with the constructive criticism are quite possibly the same people who will fail to understand the requirement of this solution, and say “it needs to be done properly”.

Let’s discuss the solution, and then take it to both a Developer and a CIO and see what they think.

What if we had an S2I image that looked for multiple package files and executed the build commands? i.e. composer.json, package.json, Gruntfile etc? Would that really be such an issue?

By default, the Red Hat SCL PHP S2I image gives you an Apache container talking to PHP without using FPM. What if we wanted NGINX & php-fpm process instead of Apache for the PHP S2I image?

We then enter the realm of running NGINX & php-fpm on the same container. Another big “no no” by the Docker gods – each container should only run one service at a time, right?

Or maybe we just want the app to work using the magic S2I builder, and not be too concerned with what someone says is ‘against the rules’, and just get the damn thing working as quickly as possible?

As you can see in this pull request, https://github.com/sclorg/s2i-php-container/pull/197 we now have a PHP S2I image, running NGINX+php-fpm, and the ability to run multiple build tools; composer, npm & grunt. More could easily be added, but this is just the start of creating an easy-to-use ready-to-roll PHP image.

We can build this image locally for CentOS or RHEL7 if you have the license:

`make build TARGET=rhel7 VERSIONS=7.1`

This will publish the image to the image repository running locally, which can then be tagged and push up to any container registry such as Docker Hub, Quay.io, ECR etc, or your own OpenShift cluster of course.

This allows us to throw in a generic PHP application, that uses frontend scaffolding tools such as less, babel, npm and also grunt. How would we deploy an application once we have the power of this magic S2I-builder? Two commands!


$ oc new-build php-71-nginx:latest –name web https://github.com/bobbydeveaux/php-show-my-hostname –strategy=source

$ oc new-app –name web –image-stream=web 


Once the service is exposed, you can head to your app running on Nginx & PHP-FPM. Not only has composer been run for you, but your frontend scaffolding tools have deployed the necessary artefacts – CSS & JS all in the correct place!

It might sound a super simple concept, but bear in mind this means each time you merge your code into {specified branch}, then your code will be built, and deployed. All in a matter of minutes thanks for using the the layers native to Docker, and the amazing orchestration powers of Kubernetes baked into the core of OpenShift.

So, maybe this pull request is a tad overkill. Maybe nginx isn’t that essential in a PaaS solution, and perhaps it would have been simpler to stick with Apache and simply add the extra build tools. But, I wanted to show you the art of what’s possible, and some of the common problems that I encounter as a DevOps consultant. Sometimes there are much more elegant solutions, sometimes we have to be creative to help get a product/app off the ground and into the wild. MVP, Agile, et al.

Is OpenShift/PaaS the answer to all your problems? Probably not. Much like Source-to-Image is never going to solve the most complex problems either. Some projects require a much more meticulous approach and more complex solutions. Sometimes you may need something much more bespoke, that you’re simply better off sticking to your IaaS/IaaC terraform / Ansible / Puppet / Consul solutions.

That’s for you to decide..!

If you’d like a free 30-day trial of OpenShift with UKCloud, sign-up here.

Related content