Getting started with Source-to-Image for building container images

S2I makes it easy to reproduce consistent container images so developers can focus on applications, not how to deploy them.
136 readers like this
136 readers like this
How Kubernetes is helping Docker blossom

Maersk Line. CC SA-BY 4.0

Source-to-Image is an excellent tool for building container images for applications in a fast, flexible, and reproducible way. Usually abbreviated as S2I, Source-to-Image takes a base "builder" image with all the libraries and build tools needed to compile an application or install dependencies (like Python's PIP or Ruby's Bundler) and a set of scripts in predefined locations that are used to build, test, and run the application. Once the builder image is created, S2I can take code from a repository, inject it into the build image, compile or install dependencies, and generate an application image with the final application ready to go.

I set out to learn how to build container images for applications written in Go (unofficially called Golang), and in over the next two articles, we will do so.

Why S2I

S2I provides a simple solution for the challenge of build reproducibility, for applications written in any programming language. That means I can reproduce consistent images to allow developers to focus on their applications rather than container images and orchestration. And, since the build environment is created ahead of time, builds take only as long as the application takes to compile or configure (which can be lightning fast with the technology behind the Go compiler).

The real beauty of S2I, in my opinion, is the ability to use builder images as templates, so that similar applications with similar configurations can be deployed without managing configuration files like Dockerfiles for every application—providing identical, reproducible environments for similar applications. Fewer templated images means less busy work on managing their updates, and a much greater likelihood that I can trust they stay up-to-date.

Many official Source-to-Image builder images already exist (e.g., Python S2I, Ruby S2I), but it's also simple to make one suit specific needs.

S2I requirements

Only four files are required to make a build an S2I-compatible image, though a few more can come in handy. The following comes straight from the S2I README documentation:

File Required? Description
Dockerfile Yes Defines the base builder image
s2i/bin/assemble Yes Script that builds the application
s2i/bin/usage No Script that prints the usage of the builder
s2i/bin/run Yes Script that runs the application
s2i/bin/save-artifacts No Script for incremental builds that saves the built artifacts
test/run No Test script for the builder image
test/test-app Yes Tests application source code

The builder image is created from the Dockerfile; therefore the Dockerfile will contain all the packages and libraries needed to compile, build, and run the source code. The Dockerfile will also need to copy the s2i/bin/* and test/* files into the resulting image to allow S2I to use them.

The s2i/bin/assemble script contains the logic to build the application or install its dependencies. For example, if the builder images were for Python applications, the assemble script would probably run pip install to install the dependencies from the requirements.txt file. For Go, the assemble script will run go get, among other things.

The s2i/bin/run script should be set as the CMD or ENTRYPOINT in the Dockerfile and is responsible for starting the application when the application image runs. In most cases, this script is required, because the image resulting from the S2I build is what runs the application. For a Go builder, it is not strictly necessary, but it can be helpful for testing an application.

The s2i/bin/save-artifacts script takes all the artifacts required for the application to run and streams them through the tar command to stdout. This allows the builder image to do incremental builds or enables us to extract the compiled binary so it can be included in a subsequent build.

These script files can be written in any language, as long as they can be executed in the container built from the Dockerfile.

Note: Despite what the documentation says, the test/test-app file is not required. If you're using the s2i create command to scaffold a new Source-to-Image builder, some blank tests are set up for you, but they are not strictly necessary. Additionally, the run script is required for most Source-to-Image builders, but for the Golang builder image we will create in this series, it is just a convenience. 

We also need the Source-to-Image software to build the runtime or application images, but it doesn't necessarily have to have to be installed on the local system. We could create our entire build pipeline in OKD or OpenShift Container Platform and do all our builds there. It is just easier to develop and test images with the software installed locally.

Grab the latest release of Source-to-Image for your platform or install it with your distribution's package manager (e.g., dnf install s2i).

We now have S2I installed and a good understanding of what it takes to start designing our builder. In the next article, we will walk through good practices for the Dockerfile configuration (including avoiding root privileges) and see an example build.

As we continue the four-part series, we will work our way through using the S2I requirements, then building an image template for an application written in Go, and finally how to use S2I with OKD or OpenShift Container Platform buildConfigs to automate image build pipelines. Do you have a question on whether you should use S2I? Feel free to ask me in the comments.

What to read next
Chris Collins
Chris Collins is an SRE at Red Hat and an Correspondent with a passion for automation, container orchestration and the ecosystems around them, and likes to recreate enterprise-grade technology at home for fun.


Creative Commons LicenseThis work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.