Kahibaro
Discord Login Register

Source-to-Image (S2I)

Concept and Workflow of S2I

Source-to-Image (S2I) is an OpenShift build mechanism that turns application source code into a runnable container image without requiring you to write a Dockerfile. It is designed to:

At a high level, S2I:

  1. Starts from a builder image that knows how to build and run a specific type of application (e.g., Python, Node.js, Java).
  2. Adds your source code (e.g., from Git) into that builder image.
  3. Runs a build process inside the container to produce your application artifact (e.g., compiled binaries, JAR/WAR files, static assets).
  4. Produces a new runtime image that contains both the runtime environment and your built application.

Typical S2I flow in OpenShift:

  1. User input: You provide a Git repo URL (or local source) and pick a builder image.
  2. OpenShift build: OpenShift starts a build pod using the builder image.
  3. Build scripts: The builder image runs S2I scripts (assemble, optional tests, etc.).
  4. Resulting image: A new image is created and stored in an image registry or image stream.
  5. Deployment: OpenShift uses that image in a Deployment/DeploymentConfig to run pods.

S2I Builder Images

An S2I builder image is a container image prepared to work with S2I. It contains:

OpenShift provides many official builder images, typically published by Red Hat and exposed in the OpenShift web console as “QuickStarts” or “builder” images. Examples:

When you choose a builder image, you effectively choose:

You can also create custom builder images when the built-in ones do not match your requirements (e.g., special native dependencies, specific build tool versions, custom test frameworks).

S2I Scripts and Their Roles

The core of S2I behavior is defined by a small set of scripts inside the builder image. They are typically located under /usr/libexec/s2i or /usr/local/s2i.

The standard S2I scripts are:

Typical responsibilities of assemble:

Typical responsibilities of run:

Creating and Using S2I Builds in OpenShift

OpenShift exposes S2I through BuildConfigs and the web console. While details of BuildConfigs are handled in other chapters, here is how S2I fits into actual usage.

Creating an S2I application from the web console

A typical workflow:

  1. In the OpenShift web console, choose “Create” or “+Add”.
  2. Select “From Git” (or similar).
  3. Enter:
    • Git repository URL
    • (Optional) Git reference (branch/tag) and context directory
  4. Choose a builder image (e.g., Node.js, Python, Java).
  5. Configure:
    • Application name
    • Resource limits, environment variables (as needed)
  6. Confirm to create:
    • A BuildConfig of type Source
    • An ImageStream for the built image
    • A Deployment/DeploymentConfig and a Service (and possibly a Route)

OpenShift then:

Creating an S2I build with `oc new-app`

From the CLI, S2I-based applications are typically created with oc new-app. Basic patterns:

  oc new-app registry.redhat.io/rhscl/nodejs-14-rhel7~https://github.com/example/my-node-app.git
  oc new-app https://github.com/example/my-python-app.git

In both cases, OpenShift:

To view the build:

oc get builds
oc logs build/<build-name>

To start a new build manually:

oc start-build <buildconfig-name> --follow

Incremental Builds with S2I

Incremental builds allow S2I to reuse artifacts from a previous build image (e.g., downloaded dependencies) to speed up subsequent builds. This is useful for:

Key aspects:

Example BuildConfig excerpt for enabling incremental builds (conceptually):

yaml
strategy:
  type: Source
  sourceStrategy:
    from:
      kind: ImageStreamTag
      name: my-builder-image:latest
    incremental: true

With incremental builds enabled:

  1. The S2I build runs save-artifacts against the previous build image.
  2. The results are injected into the new build container.
  3. assemble uses those artifacts, avoiding full dependency downloads/compiles.

Incremental builds improve build times but:

Customizing S2I Builds

You can adjust S2I behavior without modifying the builder image by:

Some common customization mechanisms:

Environment variables

Many official builder images support environment variables to tweak behavior:

You can define env vars:

Example:

oc new-app \
  registry.redhat.io/openjdk/openjdk-11-rhel8~https://github.com/example/my-java-app \
  -e MAVEN_MIRROR_URL=http://my-maven-mirror:8081/repository/maven-public

Using configuration files in your repo

Many S2I builder images look for specific files in your source tree:

Placing these files correctly influences:

Overriding S2I scripts

If you need more control, you can override S2I scripts without rebuilding the builder image:

This approach lets you:

S2I vs Dockerfile-Based Builds (in Practice)

While the detailed comparison of build strategies belongs elsewhere, some S2I-specific aspects are important when choosing between S2I and Dockerfile builds:

S2I strengths:

Typical use cases where S2I is a good fit:

Cases where Dockerfile-based builds might be preferred:

Designing Custom S2I Builder Images

When the built-in builder images are not enough, you can build custom S2I builder images tailored to your environment. Designing one involves:

  1. Start from a base image
    • Choose a minimal OS image approved by your organization.
    • Install language runtime and build tools.
  2. Install the S2I scripts
    • Install the S2I scripts package (e.g., s2i tooling) or copy scripts into /usr/libexec/s2i or similar.
    • Implement:
      • assemble
      • run
      • save-artifacts (if you want incremental support)
      • usage (optional)
  3. Define conventions
    • Decide where source code will live (e.g., /opt/app-root/src).
    • Define where caches and artifacts are stored (e.g., /opt/app-root/.cache).
    • Set environment variables that apps can rely on (APP_ROOT, HOME, etc.).
  4. Document usage
    • Clearly document:
      • Required env vars
      • Expected project structure
      • Supported frameworks or build tools
    • Make this documentation available via usage and internal docs.
  5. Publish the image
    • Push to your internal registry.
    • Optionally expose it as an ImageStream in OpenShift.
    • Optionally integrate it into the OpenShift web console catalog.

This pattern allows platform teams to standardize how specific technologies (e.g., internal frameworks, data science stacks, HPC toolchains) are built in a secure, repeatable way.

Integrating S2I with the Deployment Lifecycle

In OpenShift, S2I is tightly integrated with the application lifecycle:

Key triggers you can use with S2I:

This linkage makes S2I a foundational piece for:

Practical Tips and Common Pitfalls with S2I

Some practical considerations when using S2I:

Using S2I effectively means leveraging these conventions and tools so that developers can focus on writing code, while OpenShift and the platform team handle the complexity of building, packaging, and running containerized applications.

Views: 12

Comments

Please login to add a comment.

Don't have an account? Register now!