Integrate Jib for OCI image building #36

Open
opened 2026-01-03 23:45:07 +00:00 by KofTwentyTwo · 0 comments
KofTwentyTwo commented 2026-01-03 23:45:07 +00:00 (Migrated from github.com)

Part of #13

User Story

As a developer, I want qctl to build OCI container images using Jib so that I can package my application without requiring Docker to be installed.

Design

Why Jib?

  • No Docker daemon required (builds directly to registry or tarball)
  • Fast incremental builds (separates dependencies from application)
  • Reproducible builds (deterministic layer ordering)
  • Native Java integration (Maven/Gradle plugins or Core API)

Integration Approach

Use Jib Core API (not Maven plugin) for flexibility:

Jib.from("eclipse-temurin:21-jre")
   .addLayer(List.of(dependencyJars), "/app/libs")
   .addLayer(List.of(applicationJar), "/app")
   .setEntrypoint("java", "-jar", "/app/application.jar")
   .containerize(Containerizer.to(RegistryImage.named("registry/app:v1")));

Configuration

Project-level qrun.yaml:

package:
  baseImage: eclipse-temurin:21-jre
  ports:
    - 8080
  jvmFlags:
    - "-Xmx512m"
    - "-XX:+UseG1GC"
  mainClass: com.example.MyApp  # Auto-detected if not specified
  user: 1000:1000

Build Modes

Mode Command Output
Local tarball qrun package --local target/app.tar
Docker daemon qrun package --docker Local Docker image
Registry qrun package --registry Push to configured registry

Files to Create/Modify

File Action Description
qctl-qrun/pom.xml Modify Add jib-core dependency
JibBuilder.java Create Wraps Jib Core API
PackageConfig.java Create Configuration model for packaging
QrunConfig.java Create Parses qrun.yaml
PackageCommand.java Modify Wire up JibBuilder

Implementation Tasks

  • Add com.google.cloud.tools:jib-core:0.27.0 dependency
  • Create PackageConfig record for build configuration
  • Create QrunConfig for parsing qrun.yaml
  • Implement JibBuilder wrapper class
  • Auto-detect main class from JAR manifest
  • Support custom base images via config
  • Support custom JVM flags
  • Support port exposure configuration
  • Support user/group configuration
  • Implement --local mode (tarball output)
  • Implement --docker mode (Docker daemon)
  • Add progress output during build
  • Add unit tests with mock registry

Acceptance Criteria

  • qrun package builds OCI image without Docker
  • Base image configurable via qrun.yaml
  • JVM flags applied correctly
  • Ports exposed in image metadata
  • Main class auto-detected or configurable
  • Build completes in under 30s for incremental
  • Works on Linux, macOS, and Windows
Part of #13 ## User Story As a **developer**, I want qctl to build OCI container images using Jib so that I can package my application without requiring Docker to be installed. ## Design ### Why Jib? - No Docker daemon required (builds directly to registry or tarball) - Fast incremental builds (separates dependencies from application) - Reproducible builds (deterministic layer ordering) - Native Java integration (Maven/Gradle plugins or Core API) ### Integration Approach Use Jib Core API (not Maven plugin) for flexibility: ```java Jib.from("eclipse-temurin:21-jre") .addLayer(List.of(dependencyJars), "/app/libs") .addLayer(List.of(applicationJar), "/app") .setEntrypoint("java", "-jar", "/app/application.jar") .containerize(Containerizer.to(RegistryImage.named("registry/app:v1"))); ``` ### Configuration Project-level `qrun.yaml`: ```yaml package: baseImage: eclipse-temurin:21-jre ports: - 8080 jvmFlags: - "-Xmx512m" - "-XX:+UseG1GC" mainClass: com.example.MyApp # Auto-detected if not specified user: 1000:1000 ``` ### Build Modes | Mode | Command | Output | |------|---------|--------| | Local tarball | `qrun package --local` | `target/app.tar` | | Docker daemon | `qrun package --docker` | Local Docker image | | Registry | `qrun package --registry` | Push to configured registry | ## Files to Create/Modify | File | Action | Description | |------|--------|-------------| | `qctl-qrun/pom.xml` | Modify | Add jib-core dependency | | `JibBuilder.java` | Create | Wraps Jib Core API | | `PackageConfig.java` | Create | Configuration model for packaging | | `QrunConfig.java` | Create | Parses qrun.yaml | | `PackageCommand.java` | Modify | Wire up JibBuilder | ## Implementation Tasks - [ ] Add `com.google.cloud.tools:jib-core:0.27.0` dependency - [ ] Create `PackageConfig` record for build configuration - [ ] Create `QrunConfig` for parsing `qrun.yaml` - [ ] Implement `JibBuilder` wrapper class - [ ] Auto-detect main class from JAR manifest - [ ] Support custom base images via config - [ ] Support custom JVM flags - [ ] Support port exposure configuration - [ ] Support user/group configuration - [ ] Implement `--local` mode (tarball output) - [ ] Implement `--docker` mode (Docker daemon) - [ ] Add progress output during build - [ ] Add unit tests with mock registry ## Acceptance Criteria - [ ] `qrun package` builds OCI image without Docker - [ ] Base image configurable via `qrun.yaml` - [ ] JVM flags applied correctly - [ ] Ports exposed in image metadata - [ ] Main class auto-detected or configurable - [ ] Build completes in under 30s for incremental - [ ] Works on Linux, macOS, and Windows
Sign in to join this conversation.