> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Builds

> Guide to OpenShift build strategies, BuildConfigs, ImageStreams, S2I and Docker examples, YAML configuration, web console import, build triggers, and best practices for reproducible container images.

Welcome — in this lesson we'll examine OpenShift builds in detail. You'll learn the available build strategies, how to inspect existing BuildConfigs, and how to create new BuildConfigs using YAML. The examples use YAML and common container build artifacts; a basic familiarity with YAML and container images (Docker) will help.

Key topics covered:

* Example application to build
* Docker build strategy
* Source-to-Image (S2I) strategy
* Custom/artifact builds overview
* ImageStreams and why they matter
* Inspecting and creating BuildConfigs (S2I and Docker examples)
* Importing YAML via the web console
* Best practices and summary

If you need a quick refresher on YAML or Kubernetes concepts, see the Links and References at the end.

## Example application

Here is a minimal Flask web application that we will use as the example source to build into a container image:

```python theme={null}
# app.py
import os
from flask import Flask

app = Flask(__name__)

@app.route("/")
def main():
    return "Welcome!"

@app.route("/how-are-you")
def hello():
    return "I am good, how about you?"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080)
```

Kubernetes and OpenShift expect applications to be packaged as container images, so the next step is creating a build process that converts source code into a runnable image.

## Build strategies overview

OpenShift supports several build strategies. Choose the one that best fits your workflow and control needs.

| Build Strategy | When to use | Key points |
| - | -: | - |
| Source (S2I) | Rapid app iteration, no Dockerfile needed | Uses a builder image (e.g., `openshift/python:3.6`) to assemble the app. Good for language-centric workflows. |
| Docker | Full control over image construction | Requires a `Dockerfile` in the repo. Gives precise control over every image layer. |
| Custom / Artifact | Produce artifacts (JAR, wheel) or run custom tooling | Useful for advanced pipelines or when you need non-image outputs. |

## Docker build strategy

A Docker build uses a `Dockerfile` placed alongside your application sources. OpenShift's Docker build strategy runs the Docker build and pushes the resulting image to the internal registry.

A minimal Dockerfile for the Flask app (using Python 3) might look like this:

```dockerfile theme={null}
# Dockerfile
FROM ubuntu:16.04

RUN apt-get update && apt-get install -y python3 python3-pip \
  && rm -rf /var/lib/apt/lists/*

RUN pip3 install flask

COPY app.py /opt/app.py

ENV FLASK_APP=/opt/app.py
EXPOSE 8080
CMD ["flask", "run", "--host=0.0.0.0", "--port=8080"]
```

When OpenShift runs this Docker build, the image is produced and pushed to the cluster's internal registry (often referenced via an ImageStream).

## Source-to-Image (S2I) build strategy

Source-to-Image (S2I) is a higher-level build strategy. Instead of a `Dockerfile`, S2I injects your source into a pre-built builder image (for example, an official Python builder). The builder image contains scripts (assemble/run) that create the final image.

If you use the OpenShift web console and select the Python application from the catalog, OpenShift commonly creates an S2I BuildConfig automatically.

## Custom builds and artifact builds

When you need to produce build artifacts (for example, JARs, Python wheels, or other packaged outputs) rather than a finished container image, consider a custom build. Custom builds allow arbitrary build tooling and are suitable for CI workflows that output artifacts consumed by other parts of your pipeline.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/1i2YcqiBKQjc0R77/images/OpenShift-3-for-the-Absolute-Beginners/Concepts-Builds-and-Deployments/Builds/build-strategy-custom-java-python-ruby.jpg?fit=max&auto=format&n=1i2YcqiBKQjc0R77&q=85&s=399f72c52a04c118e456a0bc6f60f57a" alt="A presentation slide titled &#x22;Build Strategy&#x22; showing a &#x22;Custom Build&#x22; badge and icons for Java, Python, and Ruby. Below each language are briefcase icons labeled app.jar, app.tar.gz, and app.gem to represent build artifacts." width="1920" height="1080" data-path="images/OpenShift-3-for-the-Absolute-Beginners/Concepts-Builds-and-Deployments/Builds/build-strategy-custom-java-python-ruby.jpg" />
</Frame>

## ImageStreams

Builds (S2I, Docker, custom) depend on builder images. These images can originate from Docker Hub, a private registry, or the OpenShift internal registry. Relying directly on external image names and tags can be brittle because tags can change upstream.

ImageStreams provide an abstraction: they map an internal image name (for example, `python:3.6`) to a particular image reference (or digest). This lets BuildConfigs and DeploymentConfigs refer to a stable, internal name while you control exactly which external image that name maps to.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/1i2YcqiBKQjc0R77/images/OpenShift-3-for-the-Absolute-Beginners/Concepts-Builds-and-Deployments/Builds/image-stream-gear-python-docker-code.jpg?fit=max&auto=format&n=1i2YcqiBKQjc0R77&q=85&s=bb2f1d31aa6d520f1329ee8beb197b82" alt="A presentation slide titled &#x22;Image Stream&#x22; with a large red gear icon centered. To the left and right are labels &#x22;Python Image&#x22; and &#x22;Application Image&#x22; (the right shows a small red package/Docker icon), and the word &#x22;Code&#x22; appears below." width="1920" height="1080" data-path="images/OpenShift-3-for-the-Absolute-Beginners/Concepts-Builds-and-Deployments/Builds/image-stream-gear-python-docker-code.jpg" />
</Frame>

Example external image references that an ImageStream might abstract:

* `172.30.1.1:5000/myproject/java:latest`
* `docker.io/centos/python-27:latest`
* `other-registry.example.com/ruby/ruby:2.0`

ImageStreams can be updated to point to a specific image ID (sha256 digest), for example:

```text theme={null}
sha256:08b750083d53e8fdcf09ab99bc30549141ea44c90763d3e972be264fbe8d706
```

Because ImageStreams track by image ID, your builds and deployments can remain repeatable even if an external tag changes.

## Viewing a BuildConfig

OpenShift's web console provides a BuildConfig view with important details:

* Build strategy (Source, Docker, Custom)
* Source repository and ref (branch/tag)
* Builder image or ImageStream used
* Output ImageStream
* Run Policy (e.g., Serial, Parallel)
* Build triggers (GitHub, Generic, ImageChange)

You can edit or inspect a BuildConfig's YAML via Actions → Edit YAML in the console. It’s a convenient way to copy or modify the BuildConfig definition.

## Example S2I BuildConfig (yaml)

Here is a complete S2I BuildConfig for the Flask app. Save this as `s2i-build-config.yaml` to create or inspect the BuildConfig in your project.

```yaml theme={null}
# s2i-build-config.yaml
kind: BuildConfig
apiVersion: build.openshift.io/v1
metadata:
  name: simple-webapp
spec:
  runPolicy: Serial
  triggers:
    - type: GitHub
      github:
        secret: "b5e471d57f79f52e"
    - type: Generic
      generic:
        secret: "4be5b473f9985dcf"
    - type: ImageChange
  source:
    git:
      uri: "https://github.com/mmumshad/simple-webapp-flask.git"
      ref: master
  strategy:
    type: Source
    sourceStrategy:
      from:
        kind: ImageStreamTag
        name: "python:3.6"
  output:
    to:
      kind: ImageStreamTag
      name: "simple-webapp:latest"
```

## Creating a Docker build BuildConfig

To switch from an S2I build to a Docker build, create a BuildConfig that sets `strategy.type` to `Docker` and points `source.git.uri` to a repository with a `Dockerfile`.

Save the following example as `docker-build-config.yaml` or paste it into the console Import YAML dialog:

```yaml theme={null}
# docker-build-config.yaml
kind: BuildConfig
apiVersion: build.openshift.io/v1
metadata:
  name: simple-webapp-docker
spec:
  runPolicy: Serial
  triggers:
    - type: GitHub
      github:
        secret: "b5e471d57f79f52e"
    - type: Generic
      generic:
        secret: "4be5b473f9985dcf"
    - type: ImageChange
  source:
    git:
      uri: "https://github.com/mmumshad/simple-webapp-docker.git"
      ref: master
  strategy:
    type: Docker
    dockerStrategy:
      from:
        kind: DockerImage
        name: "ubuntu:16.04"
  output:
    to:
      kind: ImageStreamTag
      name: "simple-webapp:latest"
```

## Importing the YAML in the web console

Follow these steps to create a BuildConfig from YAML using the OpenShift web console:

1. In your project view, click Add to Project → Import YAML.
2. Paste the contents of the desired BuildConfig YAML (for example, `docker-build-config.yaml`) into the editor.
3. Click Create.

After creation, open the BuildConfig to confirm the build strategy, source repo, and output ImageStream. To start a build manually, click Start Build. Depending on the Run Policy, new builds may be queued while another build is running.

You can also trigger builds from the CLI. For example:

```bash theme={null}
oc start-build simple-webapp      # starts a build for the BuildConfig named simple-webapp
oc logs -f bc/simple-webapp       # stream build logs
```

## Note about image references and updates

<Callout icon="lightbulb" color="#1CB2FE">
  Use ImageStreams to decouple your BuildConfigs and DeploymentConfigs from external registry tag churn. ImageStreams let you control when to update to a newer image by updating the ImageStream mapping rather than changing multiple BuildConfigs or DeploymentConfigs.
</Callout>

## Summary

* Docker builds require a `Dockerfile` and give you fine-grained control of image layering and contents.
* Source-to-Image (S2I) uses a builder image to assemble your application without requiring a `Dockerfile`.
* Custom builds are useful for producing artifacts or integrating bespoke build tooling.
* ImageStreams provide a stable, internal reference to images and ensure builds and deployments are repeatable by tracking image IDs.
* BuildConfig YAMLs can be authored manually and imported via the web console or created and managed via the `oc` CLI.

## Links and References

* OpenShift Builds and BuildConfigs — [https://docs.openshift.com/](https://docs.openshift.com/)
* Source-to-Image (S2I) — [https://github.com/openshift/source-to-image](https://github.com/openshift/source-to-image)
* Kubernetes Basics — [https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/](https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/openshift-3-for-the-absolute-beginners/module/685b52a9-0fc2-4fb5-8cb4-362b2ca68c6f/lesson/724a3abd-796c-4bf5-ae28-1cb42805af49" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.