Source-to-Image (S2I) for Spring Boot
Learn how Source-to-Image (S2I) builds Spring Boot applications directly from source code in OpenShift. Understand S2I architecture, build lifecycle, builder images, implementation, and enterprise best practices.
Introduction
One of the unique features that makes OpenShift different from standard Kubernetes is Source-to-Image (S2I).
Instead of requiring developers to write Dockerfiles and build container images manually, S2I allows OpenShift to:
- Clone source code from Git
- Compile the application
- Package the application
- Create a container image
- Push the image to the internal registry
- Deploy the application automatically
For Java developers, this significantly simplifies the deployment process.
Learning Objectives
By the end of this article, you will understand:
- What is Source-to-Image (S2I)?
- How S2I works
- S2I architecture
- Builder Images
- BuildConfig integration
- Spring Boot implementation
- S2I vs Docker Build
- Enterprise use cases
- Best practices
What is Source-to-Image?
Source-to-Image (S2I) is an OpenShift build strategy that creates container images directly from application source code.
Instead of writing a Dockerfile, developers simply provide:
- Git Repository
- Builder Image
- BuildConfig
OpenShift performs the rest automatically.
Traditional Docker Build
flowchart LR
DEV["Developer"]
GIT["Git Repository"]
CI["CI/CD Pipeline"]
MAVEN["Maven Package"]
DOCKER["Docker Build"]
IMAGE["Container Image"]
REG["Container Registry"]
subgraph OCP["OpenShift Cluster"]
DEPLOY["Deployment"]
POD["Application Pod"]
end
DEV --> GIT
GIT --> CI
CI --> MAVEN
MAVEN --> DOCKER
DOCKER --> IMAGE
IMAGE --> REG
REG --> DEPLOY
DEPLOY --> POD
Developers are responsible for building and maintaining Docker images.
Source-to-Image Workflow
flowchart LR
DEV["Developer"]
GIT["Git Repository"]
BC["BuildConfig"]
S2I["S2I Builder"]
MAVEN["Maven Build"]
IMAGE["Container Image"]
IS["ImageStream"]
DEPLOY["Deployment"]
PODS["Running Pods"]
DEV --> GIT
GIT --> BC
BC --> S2I
S2I --> MAVEN
MAVEN --> IMAGE
IMAGE --> IS
IS --> DEPLOY
DEPLOY --> PODS
OpenShift handles the entire build process.
S2I Architecture
flowchart TD
GIT["Git Repository"]
BC["BuildConfig"]
BUILDPOD["Build Pod"]
BUILDER["Builder Image"]
MAVEN["Maven Package"]
RUNTIME["Runtime Image"]
IS["ImageStream"]
DEPLOY["Deployment"]
GIT --> BC
BC --> BUILDPOD
BUILDPOD --> BUILDER
BUILDER --> MAVEN
MAVEN --> RUNTIME
RUNTIME --> IS
IS --> DEPLOY
How S2I Works
The build process consists of several stages.
sequenceDiagram
participant Developer
participant Git
participant BuildConfig
participant Build Pod
participant ImageStream
participant Deployment
Developer->>Git: Push Code
Git->>BuildConfig: Trigger Build
BuildConfig->>Build Pod: Create Build Pod
Build Pod->>Build Pod: Maven Build
Build Pod->>ImageStream: Push Image
ImageStream->>Deployment: Deploy Image
What is a Builder Image?
A Builder Image is a preconfigured container image that contains everything needed to build an application.
For Java applications, it typically includes:
- Java
- Maven
- Linux
- Build scripts
- S2I tooling
Examples:
- OpenJDK 17
- OpenJDK 21
- Red Hat UBI Java
Builder Image Architecture
flowchart TD
BUILDER["Builder Image"]
LINUX["Linux Base"]
JAVA["Java Runtime"]
MAVEN["Maven"]
S2I["S2I Scripts"]
BUILDER --> LINUX
BUILDER --> JAVA
BUILDER --> MAVEN
BUILDER --> S2I
Developers don't need to install these tools locally.
Spring Boot Project
Example structure:
springboot-demo/
├── src/
├── pom.xml
├── mvnw
├── .mvn/
└── README.md
Notice that no Dockerfile is required.
BuildConfig Example
apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
name: springboot-demo
spec:
source:
git:
uri: https://github.com/codewithvenu/springboot-demo.git
strategy:
sourceStrategy:
from:
kind: ImageStreamTag
name: openjdk-21:latest
output:
to:
kind: ImageStreamTag
name: springboot-demo:latest
Create BuildConfig
oc apply -f buildconfig.yaml
Verify:
oc get buildconfigs
Start S2I Build
oc start-build springboot-demo
Follow logs:
oc logs -f build/springboot-demo-1
Build Lifecycle
flowchart LR
CLONE["Clone Source"]
DEPS["Download Dependencies"]
MAVEN["Maven Package"]
IMAGE["Create Image"]
PUSH["Push Image"]
DEPLOY["Deploy"]
CLONE --> DEPS
DEPS --> MAVEN
MAVEN --> IMAGE
IMAGE --> PUSH
PUSH --> DEPLOY
Every stage executes automatically.
Build Pod
OpenShift creates a temporary Build Pod.
Responsibilities:
- Clone Git repository
- Download Maven dependencies
- Compile source code
- Package JAR
- Build image
- Push image
After completion, the Build Pod is removed.
Build Pod Architecture
graph TD
A["Build Pod"]
B["Git Clone"]
C["Maven Build"]
D["Package Application"]
E["Create Container Image"]
A --> B
A --> C
A --> D
A --> E
ImageStream Integration
The generated image is stored inside an ImageStream.
flowchart LR
S2I["S2I Build"]
IS["ImageStream"]
DEPLOY["Deployment"]
PODS["Pods"]
S2I --> IS
IS --> DEPLOY
DEPLOY --> PODS
Deployments can automatically react to new images.
Enterprise Banking Example
Suppose the Payment Service is updated.
flowchart LR
DEV["Developer"]
GIT["GitHub Repository"]
BC["BuildConfig"]
BUILDPOD["Build Pod"]
IS["ImageStream"]
DC["DeploymentConfig"]
POD["Payment Pods"]
ROUTE["OpenShift Route"]
USER["Customers"]
DEV --> GIT
GIT --> BC
BC --> BUILDPOD
BUILDPOD --> IS
IS --> DC
DC --> POD
POD --> ROUTE
ROUTE --> USER
A simple Git push triggers a complete deployment.
Binary Build vs S2I
| Binary Build | S2I |
|---|---|
| Upload JAR | Upload Source Code |
| Maven outside OpenShift | Maven inside OpenShift |
| Manual Packaging | Automatic Packaging |
| Useful for offline builds | Best for CI/CD |
Docker Build vs S2I
| Docker Build | S2I |
|---|---|
| Requires Dockerfile | No Dockerfile |
| Manual image creation | Automatic image creation |
| Full image control | Standardized builds |
| Flexible | Faster development |
Advantages of S2I
- No Docker knowledge required
- Faster developer onboarding
- Standardized builds
- Secure build environment
- Integrated with BuildConfig
- Automatic deployments
- Ideal for Java applications
Common S2I Commands
Create Build:
oc start-build springboot-demo
List Builds:
oc get builds
View Logs:
oc logs build/springboot-demo-1
Cancel Build:
oc cancel-build springboot-demo-2
Delete Build:
oc delete build springboot-demo-1
Build Logs
Typical output:
Cloning repository...
Downloading Maven dependencies...
Compiling Java sources...
Packaging Spring Boot application...
Creating container image...
Pushing image...
Build completed successfully.
Best Practices
- Keep Git repositories clean.
- Use Maven Wrapper (
mvnw). - Enable Git webhooks.
- Use immutable image tags.
- Keep BuildConfigs in source control.
- Monitor build logs.
- Separate Dev, QA, and Production builds.
- Use ImageStreams for version management.
Common Mistakes
❌ Building Docker images manually for every change.
❌ Using latest image tags.
❌ Ignoring build failures.
❌ Hardcoding credentials.
❌ Not using BuildConfig triggers.
S2I vs Docker Decision Matrix
| Requirement | Recommended |
|---|---|
| Standard Spring Boot App | S2I |
| Custom OS Packages | Docker Build |
| Simple Git Deployment | S2I |
| Full Image Customization | Docker Build |
| Enterprise CI/CD | S2I |
Summary
Source-to-Image (S2I) is one of OpenShift's most powerful features for Java developers.
Key takeaways:
- S2I builds container images directly from source code.
- No Dockerfile is required for standard Spring Boot applications.
- BuildConfig defines how the application is built.
- Builder Images provide Java, Maven, and build tools.
- ImageStreams store generated images.
- Git pushes can automatically trigger new deployments.
- S2I simplifies enterprise CI/CD while enforcing consistent build practices.
Interview Questions
- What is Source-to-Image (S2I)?
- How does S2I differ from Docker Build?
- What is a Builder Image?
- What is the purpose of BuildConfig?
- Does S2I require a Dockerfile?
- What happens inside the Build Pod?
- How does S2I integrate with ImageStreams?
- What triggers an S2I build?
- When should you choose S2I over Docker Build?
- Why is S2I commonly used for Spring Boot applications?