Walk through the jib { from, to, container } DSL: what does each block configure and what are the key fields?
answer
- from = base image + platforms
- to = image name + tags + auth
- container = mainClass, jvmFlags, ports, user, labels
- mainClass auto-detected, set for Boot/Kotlin
- entrypoint INHERIT keeps base
basics
~10 sfrom sets the base image. to sets the target image name/tags and auth. container configures runtime: jvmFlags, mainClass, ports, entrypoint, environment, labels.
solid answer
~40 sThe `jib { }` block has three main sections. **`from`** chooses the base image (`image = "eclipse-temurin:21-jre"`) and its `auth`/`platforms` (for multi-arch). **`to`** names the output: `image` (the full registry/repo:tag), extra `tags`, and registry `auth`/credHelper. **`container`** describes how the JVM app runs inside the image: `mainClass`, `jvmFlags` (e.g. `-Xms512m`), `ports`, `environment`, `labels`, `user`, `workingDirectory`, `creationTime`, and `entrypoint` (set to `INHERIT` to reuse the base image's entrypoint, or omit to let Jib generate the java launch). Jib auto-detects `mainClass` from the build when unambiguous, but you set it explicitly for Spring Boot/Kotlin (`AppKt`) apps. These blocks are the whole contract — no Dockerfile instructions involved.
code
kotlin · 13 linesjib {
from { image = "eclipse-temurin:21-jre" }
to {
image = "ghcr.io/acme/billing"
tags = setOf("latest", project.version.toString())
}
container {
mainClass = "com.acme.billing.AppKt"
jvmFlags = listOf("-XX:MaxRAMPercentage=75")
ports = listOf("8080")
user = "1000:1000"
}
}go deeper
Know from = base, to = target name, container = runtime settings like mainClass.
List the key fields per block and know mainClass/jvmFlags/ports/user live in container.
Use container.user and labels for hardening/metadata and explain multi-tag pushes via to.tags.
Standardize a shared Jib convention (base image, non-root user, OCI labels) across services via a convention plugin.
## The three configuration blocks ### `from` — the base image Controls what your app layers sit on top of. - `image` — base reference, e.g. `eclipse-temurin:21-jre`. If omitted, Jib uses a default distroless-style JRE base. - `auth { username/password }` or `credHelper` — credentials to pull a private base. - `platforms { platform { architecture = "arm64"; os = "linux" } }` — build a multi-arch image. ### `to` — the destination image Controls naming and where it is pushed. - `image` — full target, e.g. `ghcr.io/acme/billing:1.4.0`. - `tags` — additional tags applied to the same digest, e.g. `setOf("latest", gitSha)`. - `auth { }` / `credHelper` — registry credentials for the push. ### `container` — runtime configuration This is the equivalent of the runtime-affecting Dockerfile instructions. - `mainClass` — entrypoint class. Auto-detected when unambiguous; set explicitly for Spring Boot (`org.springframework.boot.loader...` is handled by the Boot integration) or Kotlin (`com.acme.AppKt`). - `jvmFlags` — list of JVM args baked into the launch command, e.g. `listOf("-Xms256m", "-XX:+UseG1GC")`. - `ports` — exposed ports metadata, e.g. `listOf("8080")`. - `environment` — env vars map. - `labels` — OCI image labels (useful for org.opencontainers.* metadata). - `user` — run as a non-root user, e.g. `"1000:1000"`. - `workingDirectory`, `creationTime`, `format` (`OCI` or `Docker`). - `entrypoint` — set to `"INHERIT"` to keep the base image's entrypoint, or leave default so Jib builds the `java -cp ... mainClass` launcher. ## Example ```kotlin jib { from { image = "eclipse-temurin:21-jre" } to { image = "ghcr.io/acme/billing" tags = setOf("latest", project.version.toString()) } container { mainClass = "com.acme.billing.AppKt" jvmFlags = listOf("-Xms256m", "-XX:MaxRAMPercentage=75") ports = listOf("8080") user = "1000:1000" labels = mapOf("org.opencontainers.image.source" to "https://github.com/acme/billing") } } ``` ## Why this matters Everything about the produced image — base, name, JVM tuning, security user, metadata — lives in one typed block, version-controlled with the build, with no shell scripting. That makes images reproducible and reviewable.
- Where do you set JVM memory flags for the running container?In `container { jvmFlags = listOf("-Xms...", "-XX:MaxRAMPercentage=...") }`. They are baked into the generated launch command.
- How do you run the container as a non-root user with Jib?Set `container { user = "1000:1000" }` (uid:gid). Jib bakes that into the image config.
- When must you set mainClass explicitly?When Jib cannot unambiguously detect it — multiple main methods, or Kotlin `AppKt` / Spring Boot layouts. Otherwise auto-detection works.
saying these in an interview costs you the question
- Putting base-image choice under `to` instead of `from`.
- Thinking jvmFlags belong in `from` or `to` rather than `container`.
- Assuming mainClass is always auto-detected (fails with multiple mains).