Creating OpenShift apps – part 2: Docker image, S2I

In this post we will see how to deploy OpenShift apps from Docker files and Docker container images using S2I, a killer feature of OpenShift.

In the previous post, we created OpenShift apps using OpenShift resources. We specified these resources using YAML files and created the constructs. But this is not how we usually create apps. We use the new-app command.

Introducing oc new-app

The oc client has a subcommand called new-app. It takes a mix of various options to create a new app. The new-app command takes the required details from command line options and creates resources like replication controllers, pods and deployments automatically, without the need to create YAML files for all of these.

For instance, let’s try to create the apache application v1 seen in our previous post using new-app.

You can see that it takes the docker image as an input and we add the “method=new-app” label to all the resources created by this run. Let’s list all the resources created by this new-app command.

You can see that it creates a pod, replication controller, a service and finally a deployment config which gets triggered when the imagestream “apache:v1” changes. How can we set the desired replicas to 2 instead of 1 now?

We use the “oc patch” to update/patch any OpenShift resource. Once you successfully patch the deployment config to 2 replicas, you should see 2 pods which match the given label.

This worked well because we already baked in our code into our docker image, in this case, adding index.html to our base apache image. What if we already have a Dockerfile specified in our codebase, and want to indicate OpenShift to deploy our app using this Dockerfile and codebase?

The new-app command helps us pull this off as well.

Creating a new app from source code

The codebase contains a go file and a Dockerfile for specifying how the image is built.

Golang minimal Dockerfile for building OpenShift app

We start from a barebones “golang:1.11-alpine” image, copy over a go executable, and note that we run the process as user 1001, a non-root user. Otherwise OpenShift is not going to run the process and the deployment will fail. Let’s see what we get when we hit the app in the browser.

$ oc expose svc/go-app
The app deployed from Golang source and a Docker image

The OpenShift build config resource

This “new-app” run created a resource type hitherto unknown to us, the build config

List all build configs

A build config tells OpenShift how to build an app. This is mostly information about the source control repository, any credentials associated with it. This can be triggered manually, or automatically by creating a webhook on the source control side(Github or Gitlab) when the source code changes. Go ahead and clone the source code and make some visible change, but make source you create the new-app using your source code’s URL. Then, we will trigger a new build,

Openshift trigger new build

The S2I build

Finally, we come to my favorite style of building OpenShift apps, the Source2Image, a.k.a S2I. I prefer this the most because it involves the least devops/container context of all the app deployment styles we’ve seen so far. In fact, teams using this need not even supply stuff like Docker files, or any OpenShift specific context when using S2I. How does that work now?

The S2I build starts when you give just the source code of your app to OpenShift. In a gist, S2I

  1. Figures out the source code of your app(i.e. this is a python app, or a Node.js app)
  2. Takes a matching base image from the existing image stream.(Ex: Fetch a Python-3.6 base image for a Python app)
  3. Injects your source code into this base image and creates an intermediate image.
  4. Deploys this intermediate image on your OpenShift cluster.

Let’s quickly see S2I in action.

OpenShift create app from S2I

If you browse the codebase, you won’t find any reference to any Docker file or OpenShift specific configuration! S2I relies on convention over configuration to make the whole process as simple as possible.

The S2I Python app which we deployed

You can even create your own custom base images. When an OpenShift cluster is installed, it creates base images in the “openshift” namespace for most popular stacks.

You can trigger a new build in a similar fashion to how we did for the Go app above. You just have to fork the repository and create a new app from that. Then make changes to that repository and trigger a new build using the “oc start-build <app-name>” command.

OpenShift S2I base images which ship by default

What if you want to build a customized version of an s2i base image, and none of the above are apt for your requirements? OpenShift has provision for creating custom S2I images as well, which will be the subject of the next post.

Up Next:

Creating OpenShift apps - part 1: using OpenShift resources

Creating OpenShift apps - part 1: using OpenShift resources