Creating a nginx s2i builder container image

Purpose

This blog article will describe how to create an OpenShift Source-to-Image container image. It will be use to build container image that could server static content via http using nginx.

Why a builder image?

By using Source-to-Image (S2I) some advantages could be gained either for your application development or platform operation:

  • Operational efficiency - By restricting build operations instead of allowing arbitrary actions, as a Dockerfile would allow, the PaaS operator can avoid accidental or intentional abuses of the build system.

  • Ecosystem - S2I encourages a shared ecosystem of images where you can leverage best practices for your applications.

  • Image flexibility - S2I scripts can be written to inject application code into almost any existing Docker image, taking advantage of the existing ecosystem.

Assuming the fact that builder image does not change, this method could be used to implement repeatable build:

  • the build process is versioned/immutable, as we know the version of the container image used to build, and therefore the versions of the scripts used to build

  • the content is versioned, as we know from which git tag the build will clone the source

  • no interference, as the builder (guy) may not inject arbitrary artifacts into the build process or source

But, this clearly leads to the fact, that we cant use a simple docker build to package up our HTML and run a webserver from that image.

Understanding Source-to-Image

As a builder image author, you must understand two basic concepts in order for your builder images to provide the best possible S2I performance: the build process and S2I scripts.

Build process

The build process is transforming the source code into artifacts, later on these artifacts can be run by OpenShift. A detailed description of the build process is part of the OpenShift documentation. Getting the source and transforming it into an artifact is the responsibility of the assemble script.

S2I scripts

Source-to-Image script are not required to be (bash) scripts, they need to be executable files, and they must at least support the following tasks: assemble and run. Both tasks are carried out by different scripts at different lifecycles of the S2I container:

  • the assemble script will get and transform the source to an artifacts, during build time

  • the run script will execute the artifact, during run time after deployment

Details can be found at S2I Requirements - S2I Scripts

Creating the Source-to-Image container image

To create a S2I builder image for static HTML content to be server by nginx the S2I scripts need to be written and all depending software needs to be packaged as a container image.

For the s2i-nginx builder image, the assemble script will do three things:

  1. copy the static files, eg. HTML, CSS, JS

  2. (optional) copy nginx config snippets

  3. (optional) copy auxiliary directory

The run script will simple run nginx with the embedded configuration.

An example

A CentOS7 based nginx 1.8 S2I builder image is provided at https://github.com/goern/CentOS-Dockerfiles/tree/feature/s2i-nginx/s2i-nginx/centos7, it container an assemble image and a run image.

All will be packaged as a Docker container image via a Dockerfile.

See it in production

While I extended the currentweather example application, I create an OpenShift build configuration to use the S2I builder image described above. The S2I image itself comes in via an ImageStream and generates a new tagged image.

The result is a HTML5/JQuery/CSS3/Patternfly web application: http://currentweather.syseng.us./

Acknowledgements

This work has been motivated by @luebken's currentweather and Tobias Florek on github