skip to content

How does Jib authenticate to registries, and how do you produce a multi-architecture image?

level: seniorimportance: nice to knowfreq 26%

answer

  1. auth: DSL > credHelper > docker config > sysprops
  2. never hardcode passwords
  3. platforms { platform { architecture/os } }
  4. pushes OCI manifest list
  5. base must publish those arches; jibDockerBuild is single-arch

basics

~10 s

Jib reads credentials from Docker config, credential helpers, or explicit from/to auth blocks. For multi-arch you list platforms under from { platforms { ... } } and Jib pushes a manifest list.

solid answer

~40 s

Jib resolves registry credentials in order: an explicit `from.auth`/`to.auth` block, a configured `credHelper`, Docker's `~/.docker/config.json` (including its credential store/helpers), and well-known CI env conventions. In practice you keep secrets out of the build by relying on `docker login` or a credential helper, and pass per-build creds via `-Djib.to.auth.username/password` or env. For **multi-architecture** images, you declare target platforms in `from { platforms { platform { architecture = "amd64"; os = "linux" }; platform { architecture = "arm64"; os = "linux" } } }`. Jib then pulls the matching base layers per platform and pushes a **manifest list (OCI image index)** so a puller automatically gets the right arch. Note multi-arch needs the base image to provide those platforms, and `jibDockerBuild` (local daemon) only loads a single platform.

code

kotlin · 13 lines
kotlin
jib {
    from {
        image = "eclipse-temurin:21-jre"
        platforms {
            platform { architecture = "amd64"; os = "linux" }
            platform { architecture = "arm64"; os = "linux" }
        }
    }
    to {
        image = "ghcr.io/acme/app:multi"
        credHelper = "ghcr"
    }
}

go deeper

for a junior

Know Jib can read Docker login credentials and that you can list platforms for multi-arch.

for a middle

Describe the credential precedence and that multi-arch produces a manifest list via from.platforms.

for a senior

Choose a secrets-safe credential strategy and explain the base-image and daemon caveats for multi-arch.

for a principal

Set org policy for credential helpers, secret injection, and which node architectures are supported across the fleet.

## Credential resolution When Jib pushes to `to.image` or pulls a private `from.image`, it needs registry credentials. It looks, in priority order, at: 1. **Explicit DSL auth** — `from { auth { username = ...; password = ... } }` / same under `to`. Useful with values injected from env, never hardcoded. 2. **Credential helper** — `from { credHelper = "ecr-login" }` or `to { credHelper = "gcr" }`, invoking a `docker-credential-<helper>` binary. 3. **Docker config** — `~/.docker/config.json`, including its `credsStore`/`credHelpers`, so a prior `docker login` just works. 4. **System properties / env** — `-Djib.to.auth.username` / `-Djib.to.auth.password`, or registry-specific env conventions in CI. Best practice: do **not** put passwords in `build.gradle.kts`. Use `docker login`, a cloud credential helper (ECR/GCR/ACR), or inject via CI secrets into system properties at invocation time. ```bash ./gradlew jib \ -Djib.to.image=ghcr.io/acme/app:$TAG \ -Djib.to.auth.username=$REG_USER \ -Djib.to.auth.password=$REG_TOKEN ``` ## Multi-architecture images Many clusters mix amd64 and arm64 nodes. A single tag should resolve to the right arch via an **OCI image index (manifest list)** — a top-level manifest pointing at per-architecture manifests. Jib builds this when you list platforms: ```kotlin jib { from { image = "eclipse-temurin:21-jre" platforms { platform { architecture = "amd64"; os = "linux" } platform { architecture = "arm64"; os = "linux" } } } to { image = "ghcr.io/acme/app:multi" } } ``` For each platform Jib selects the matching base-image layers from the base's own manifest list, assembles per-arch images, and pushes a manifest list under the single tag. A node pulling the tag automatically gets its architecture. ## Caveats - The **base image must publish** all requested platforms; otherwise Jib cannot find layers for the missing arch. - Multi-arch works on the **registry push (`jib`)** path. `jibDockerBuild` loads into the local daemon, which is single-platform, so it cannot represent a manifest list. - Jib does not cross-compile your bytecode — JVM bytecode is arch-neutral; only the base JRE layers differ per platform. ## Why this is mostly a senior/platform concern Credential strategy and multi-arch are deployment/governance decisions (where secrets live, which node architectures you support), so they sit above day-to-day app config.

  • Why might a multi-arch Jib build fail to find arm64 layers?
    Because the chosen base image does not publish an arm64/linux variant. Jib pulls per-platform base layers, so the base must provide every requested platform.
  • Can jibDockerBuild produce a multi-arch image?
    No. It loads into the local Docker daemon, which holds a single platform. Multi-arch manifest lists require the registry-push path (jib).
  • What is the safest way to supply registry credentials in CI?
    Inject them from CI secrets at invocation (system properties/env) or use a cloud credential helper — never hardcode passwords in the build script.

saying these in an interview costs you the question

  • Hardcoding registry passwords in build.gradle.kts.
  • Expecting jibDockerBuild to emit a manifest list.
  • Assuming Jib cross-compiles bytecode per architecture (it doesn't — only base layers differ).

context