# Technical Documentation: GoogleContainerTools/jib

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/GoogleContainerTools/jib)

### Overview (`README.md`)

[](https://maven-badges.herokuapp.com/maven-central/com.google.cloud.tools/jib-maven-plugin)
[](https://plugins.gradle.org/plugin/com.google.cloud.tools.jib)



[](https://slsa.dev)
[](https://gitter.im/google/jib)

# Jib

<image src="https://github.com/GoogleContainerTools/jib/raw/master/logo/jib-build-docker-java-container-image.png" alt="Jib - Containerize your Java applications." width="650px" />

| ☑️  Jib User Survey |
| :----- |
| What do you like best about Jib? What needs to be improved? Please tell us by taking a [one-minute survey](https://forms.gle/YRFeamGj51xmgnx28). Your responses will help us understand Jib usage and allow us to serve our customers (you!) better. |

## What is Jib?

Jib builds optimized Docker and [OCI](https://github.com/opencontainers/image-spec) images for your Java applications without a Docker daemon - and without deep mastery of Docker best-practices. It is available as plugins for [Maven](jib-maven-plugin) and [Gradle](jib-gradle-plugin) and as a Java library.

- [Maven](https://maven.apache.org/): See documentation for [jib-maven-plugin](jib-maven-plugin).
- [Gradle](https://gradle.org/): See documentation for [jib-gradle-plugin](jib-gradle-plugin).
- [Jib Core](jib-core): A general-purpose container-building library for Java.
- [Jib CLI](jib-cli): A command-line interface for building images that uses Jib Core.

Jib works well with Google Cloud Build. For details, see [how to use Jib on Google Cloud Build](docs/google-cloud-build.md).

For more information, check out the [official blog post](https://cloudplatform.googleblog.com/2018/07/introducing-jib-build-java-docker-images-better.html) or watch [this talk](https://www.youtube.com/watch?v=H6gR_Cv4yWI) ([slides](https://speakerdeck.com/coollog/build-containers-faster-with-jib-a-google-image-build-tool-for-java-applications)).

## Goals

* **Fast** - Deploy your changes fast. Jib separates your application into multiple layers, splitting dependencies from classes. Now you don’t have to wait for Docker to rebuild your entire Java application - just deploy the layers that changed.

* **Reproducible** - Rebuilding your container image with the same contents always generates the same image. Never trigger an unnecessary update again.

* **Daemonless** - Reduce your CLI dependencies. Build your Docker image from within Maven or Gradle and push to any registry of your choice. *No more writing Dockerfiles and calling docker build/push.*

## Quickstart

* **Maven** - See the jib-maven-plugin [Quickstart](jib-maven-plugin#quickstart).

* **Gradle** - See the jib-gradle-plugin [Quickstart](jib-gradle-plugin#quickstart).

* **Jib Core** - See the Jib Core [Quickstart](jib-core#adding-jib-core-to-your-build).

* **Jib CLI** - See the Jib CLI [doc](jib-cli).

## Examples

The [examples](examples) directory includes the following examples (and more).
   * [helloworld](examples/helloworld)
   * [Spring Boot](examples/spring-boot)
   * [Micronaut](examples/micronaut)
   * [Multi-module project](examples/multi-module)
   * [Spark Java using Java Agent](examples/java-agent)

## How Jib Works

Whereas traditionally a Java application is built as a single image layer with the application JAR, Jib's build strategy separates the Java application into multiple layers for more granular incremental builds. When you change your code, only your changes are rebuilt, not your entire application. These layers, by default, are layered on top of an [OpenJDK base image](docs/default_base_image.md), but you can also configure a custom base image. For more information, check out the [official blog post](https://cloudplatform.googleblog.com/2018/07/introducing-jib-build-java-docker-images-better.html) or watch [this talk](https://www.youtube.com/watch?v=H6gR_Cv4yWI) ([slides](https://speakerdeck.com/coollog/build-containers-faster-with-jib-a-google-image-build-tool-for-java-applications)).

See also [rules_docker](https://github.com/bazelbuild/rules_docker) for a similar existing container image build tool for the [Bazel build system](https://github.com/bazelbuild/bazel).

## Need Help?

A lot of questions are already answered!

* [Frequently Asked Questions (FAQ)](docs/faq.md)
* [Stack Overflow](https://stackoverflow.com/questions/tagged/jib)
* [GitHub issues](https://stackoverflow.com/questions/tagged/jib)

_For usage questions, please ask them on Stack Overflow._

## Privacy

See the [Privacy page](docs/privacy.md).

## Get involved with the community

We welcome contributions! Here's how you can contribute:

* [Browse issues](https://github.com/GoogleContainerTools/jib/issues) or [file an issue](https://github.com/GoogleContainerTools/jib/issues/new)
* Chat with us on [gitter](https://gitter.im/google/jib)
* Join the [jib-users mailing list](https://groups.google.com/forum/#!forum/jib-users)
* Contribute:
  * *Read the [contributing guide](https://github.com/GoogleContainerTools/jib/blob/master/CONTRIBUTING.md) before starting work on an issue*
  * Try to fix [good first issues](https://github.com/GoogleContainerTools/jib/labels/good%20first%20issue)
  * Help out on [issues that need help](https://github.com/GoogleContainerTools/jib/labels/kind%2Fquestion)
  * Join in on [discussion issues](https://github.com/GoogleContainerTools/jib/labels/discuss)

*Make sure to follow the [Code of Conduct](https://github.com/GoogleContainerTools/jib/blob/master/CODE_OF_CONDUCT.md) when contributing so we can foster an open and welcoming community.*

## Disclaimer

This is not an officially supported Google product.

---

### Overview (`examples/README.md`)

# Example projects containerizing with Jib

Please [file an issue](/../../issues/new) if you find any problems with the examples or would like to request other examples.

For examples on using Jib Core, see [jib-core/examples](../jib-core/examples).

### Simple example

See [helloworld](helloworld) for containerizing a simple `Hello World` application.

### Multi-module example (DRAFT)

See [multi-module](multi-module) for containerizing projects with multiple modules.

### Vert.x

See [vertx](vertx) for containerizing [Eclipse Vert.x](https://vertx.io/) applications.

### Spring Boot example

See [spring-boot](spring-boot) for containerizing a [Spring Boot](https://spring.io/projects/spring-boot) application and running it on [Kubernetes](https://kubernetes.io).

### Ktor example

See [ktor](ktor) for containerizing a [Ktor](https://ktor.io) Kotlin Application using the Kotlin Gradle DSL.

### Dropwizard example

See [dropwizard](dropwizard) for containerizing [Dropwizard](https://dropwizard.io) applications.

### Micronaut example

See [micronaut](micronaut) for containerizing a [Micronaut framework](https://micronaut.io/) Groovy/Java application.

### Java agents example

See [java-agent](java-agent) for launching with the Stackdriver Debugger Java agent.

### Kafka Connect+Streams example

See the following projects for using Jib-packaged applications in coordination with [Apache Kafka](http://kafka.apache.org/documentation).
  - [Kafka Streams](http://kafka.apache.org/documentation/streams) - [`OneCricketeer/kafka-streams-jib-example`](https://github.com/OneCricketeer/kafka-streams-jib-example)
  - [Kafka Connect](http://kafka.apache.org/documentation#connect) - [`OneCricketeer/apache-kafka-connect-docker`](https://github.com/OneCricketeer/apache-kafka-connect-docker)

---

### Overview (`jib-cli/README.md`)

# Jib CLI

<img src="https://img.shields.io/badge/status-preview-orange">

[](https://chocolatey.org/packages/jib)
[](https://chocolatey.org/packages/jib)
[](https://slsa.dev)

`jib` is a general-purpose command-line utility for building Docker or [OCI](https://github.com/opencontainers/image-spec) container images from file system content as well as JAR files. Jib CLI builds containers [fast and reproducibly without Docker](https://github.com/GoogleContainerTools/jib#goals) like [other Jib tools](https://github.com/GoogleContainerTools/jib#what-is-jib).

```sh
# docker not required
$ docker
-bash: docker: command not found
# build and upload an image
$ jib build --target=my-registry.example.com/built-by-jib
```

Additionally, Jib CLI can directly build an optimized image for JAR files (including Spring Boot fat JAR).
```sh
$ jib jar --target=my-registry.example.com/jar-app myapp.jar
```

The CLI tool is powered by [Jib Core](https://github.com/GoogleContainerTools/jib/tree/master/jib-core), a Java library for building containers without Docker.

## Table of Contents
* [Get the Jib CLI](#get-the-jib-cli)
  * [Download a Java Application](#download-a-java-application)
  * [Windows: Install with `choco`](#windows-install-with-choco)
  * [Build Yourself from Source (for Advanced Users)](#build-yourself-from-source-for-advanced-users)
* [Jib CLI JVM options](#jib-cli-jvm-options)
* [Supported Commands](#supported-commands)
* [Build Command](#build-command)
  * [Quickstart](#quickstart)
  * [Options](#options)
* [Jar Command](#jar-command)
  * [Quickstart](#quickstart-1)
  * [Options](#options-1)
* [War Command](#war-command)
  * [Quickstart](#quickstart-2)
  * [Options](#options-2)
* [Options Shared Between Jar and War Commands](#options-shared-between-jar-and-war-commands)
* [Common Jib CLI Options](#common-jib-cli-options)
  * [Auth/Security](#authsecurity)
  * [Info Params](#info-params)
  * [Debugging Params](#debugging-params)
* [Global Jib Configuration](#global-jib-configuration)
* [References](#references)
  * [Fully Annotated Build File (`jib.yaml`)](#fully-annotated-build-file-jibyaml)
* [Privacy](#privacy)

## Get the Jib CLI

Most users should download a ZIP archive (Java application). We are working on releasing a native executable binary using GraalVM. (Help wanted!)

### Download a Java Application

A JRE is required to run this Jib CLI distribution.

Find the [latest jib-cli 0.13.0 release](https://github.com/GoogleContainerTools/jib/releases/latest) on the [Releases page](https://github.com/GoogleContainerTools/jib/releases) and download `jib-jre-<version>.zip`.

Unzip the zip file. The zip file contains the `jib` (`jib.bat` for Windows) script at `jib/bin/`. Optionally, add the binary directory to your `$PATH` so that you can call `jib` from anywhere.

We generate [SLSA3 signatures](https://slsa.dev/) using the OpenSSF's [slsa-framework/slsa-github-generator](https://github.com/slsa-framework/slsa-github-generator) during the release process. To verify a release binary:
1. Install the verification tool from [slsa-framework/slsa-verifier#installation](https://github.com/slsa-framework/slsa-verifier#installation).
2. Download the signature file `jib-jre-<version>.zip.intoto.jsonl` from the [GitHub releases page](https://github.com/GoogleContainerTools/jib/releases/latest).
3. Run the verifier:
```shell
slsa-verifier -artifact-path jib-jre-<version>.zip -provenance jib-jre-<version>.zip.intoto.jsonl -source github.com/GoogleContainerTools/jib -branch master -workflow-input release_version=<version>
```

### Windows: Install with `choco`

On Windows, you can use the [`choco`](https://community.chocolatey.org/packages/jib) command. To install, upgrade, or uninstall Jib CLI, run the following commands from the command-line or PowerShell:
```
choco install jib
choco upgrade jib
choco uninstall jib
```

### Build Yourself from Source (for Advanced Users)

Use the `application` plugin's `installDist` task to create a runnable installation in
`build/install/jib`.  A zip and tar file are also created in `build/distributions`.
```sh
# build
$ ./gradlew jib-cli:installDist
# run
$ ./jib-cli/build/install/jib/bin/jib
```

## Jib CLI JVM options

Jib CLI is a Java application built with the [Gradle application plugin](https://docs.gradle.org/current/userguide/application_plugin.html). 
To configure JVM options for the Jib CLI process itself, you can use the `JIB_OPTS` or `JAVA_OPTS` environment variables.
This is commonly used to configure settings like a proxy by passing standard Java networking properties, as described in the [proxy configuration FAQ](../docs/faq.md#how-do-i-configure-a-proxy).

## Supported Commands

The Jib CLI supports two commands:
 1. `build` - containerizes using a [build file](#fully-annotated-build-file-jibyaml).
 2. `jar` - containerizes JAR files.
 3. `war` - containerizes WAR files.

## Build Command

This command follows the following pattern:
```
jib build --target <image name> [options]
```

### Quickstart

1. Create a hello world script (`script.sh`) containing:
    ```sh
    #!/bin/sh
    echo "Hello World"
    ```
2. Create a [build file](#fully-annotated-build-file-jibyaml). The default is a file named `jib.yaml` in the project root.
    ```yaml
    apiVersion: jib/v1alpha1
    kind: BuildFile
    
    from:
      image: ubuntu
    
    entrypoint: ["/script.sh"]
    
    layers:
      entries:
        - name: scripts
          files:
            - properties:
                filePermissions: 755
              src: script.sh
              dest: /script.sh
    ```
3. Build to docker daemon
   ```
    $ jib build --target=docker://jib-cli-quickstart
   ```
4. Run the container
   ```
    $ docker run jib-cli-quickstart
    Hello World
   ```

### Options

Optional flags for the `build` command:

Option | Description
---     | ---
`-b, --build-file` |  The path to the build file (ex: path/to/other-jib.yaml)
`-c, --context`    |  The context root directory of the build (ex: path/to/my/build/things)
`-p, --parameter`  |  Templating parameter to inject into build file, replace ${<name>} with <value> (repeatable)

## Jar Command

This command follows the following pattern:
```
jib jar --target <image name> path/to/myapp.jar [options]
```

### Quickstart

1. Have your JAR (thin or fat) ready. We will be using the [Spring Petclinic](https://projects.spring.io/spring-petclinic/) JAR in this Quickstart.
   ```
    $ git clone https://github.com/spring-projects/spring-petclinic.git
    $ cd spring-petclinic
    $ ./mvnw package
   ```
2. Containerize your JAR using the `jar` command. In the default mode (exploded), the entrypoint will be set to `java -cp /app/dependencies/:/app/explodedJar/ HelloWorld`
   ```
    $ jib jar --target=docker://cli-jar-quickstart target/spring-petclinic-*.jar
   ```
3. Run the image and open your browser at http://localhost:8080
   ```
    $ docker run -p 8080:8080 cli-jar-quickstart
   ```

### Options

Optional flags for the `jar` command:

Option | Description
---       | ---
`--jvm-flags`     | JVM arguments, example: `--jvm-flags=-Dmy.property=value,-Xshare:off`
`--mode`          | The jar processing mode, candidates: exploded, packaged, default: exploded

## War Command

This command follows the following pattern:
```
 $ jib war --target <image-name> path/to/myapp.war 
```

## Quickstart

1. Have your sample WAR ready and use the `war` command to containerize your WAR. By default, the WAR command uses [`jetty`](https://hub.docker.com/_/jetty) as the base image so the entrypoint is set to `java -jar /usr/local/jetty/start.jar --module=ee10-deploy`:
    ```
     $ jib war --target=docker://cli-war-quickstart <your-sample>.war
    ```
2.  Run the image and open your browser at http://localhost:8080
    ```
     $ docker run -p 8080:8080 cli-war-quickstart
    ```
## Options

Flags for the `war` command:

Option | Description
---       | ---
`--app-root` | The app root on the container. Customizing the app-root is helpful if you are using a different Servlet engine base image (for example, Tomcat)

## Options Shared Between the Jar and War Commands
Here are a few container configurations that can be customized when using the `jar` and `war` commands.

Option | Description
---       | ---
`--creation-time` | The creation time of the container in milliseconds since epoch or iso8601 format. Overrides the default (1970-01-01T00:00:00Z)
`--entrypoint`    | Entrypoint for container. Overrides the default entrypoint, example: `--entrypoint='custom entrypoint'`
`--environment-variables`  | Environment variables to write into container, example: `--environment-variables env1=env_value1, env2=env_value2`.
`--expose`        | Ports to expose on container, example: `--expose=5000,7/udp`.
`--from`          | The base image to use.
`--image-format`  | Format of container, candidates: Docker, OCI, default: Docker.
`--labels`        | Labels to write into container metadata, example: `--labels=label1=value1,label2=value2`.
`--program-args`  | Program arguments for container entrypoint.
`-u, --user`      | The user to run the container as, example: `--user=myuser:mygroup`.
`--volumes`       | Directories on container to hold extra volumes, example: `--volumes=/var/log,/var/log2`.

## Common Jib CLI Options

The options can either be specified in the command line or defined in a configuration file:
```
[@<filename>...]      One or more argument files containing options.
```
 
### Auth/Security

```
    --allow-insecure-registries            Allow jib to send credentials over http (insecure)
    --send-credentials-over-http           Allow jib to send credentials over http (very insecure)
```

### Registry Credentials

Credentials can be specified using credential helpers or username + password. The following options are available:

```
    --credential-helper <credHelper>      credential helper for communicating with both target and base image registries, either a path to the helper, or a suffix for an executable named `docker-credential-<suffix>`
    --to-credential-helper <credHelper>   credential helper for communicating with target registry, either a path to the helper, or a suffix for an executable named `docker-credential-<suffix>
    --from-credential-helper <credHelper> credential helper for communicating with base image registry, either a path to the helper, or a suffix for an executable named `docker-credential-<suffix>`

    --username <username>                  username for communicating with both target and base image registries
    --password <password>                  password for communicating with both target and base image registries
    --to-username <username>               username for communicating with target image registry
    --to-password <password>               password for communicating with target image registry
    --from-username <username>             username for communicating with base image registry
    --from-password <password>             password for communicating with base image registry
```
*Note* - Combinations of `credential-helper`, `username` and `password` flags come with restrictions and can be use only in the following ways:

Only Credential Helper
1. `--credential-helper`
2. `--to-credential-helper`
3. `--from-credential-helper`
4. `--to-credential-helper`, `--from-credential-helper`

Only Username and Password
1. `--username`, `--password`
2. `--to-username`, `--to-password`
3. `--from-username`, `--from-password`
4. `--to-username`, `--to-password`, `--from-username`, `--from-password`

Mixed Mode
1. `--to-credential-helper`, `--from-username`, `--from-password`
2. `--from-credential-helper`, `--to-username`, `--to-password`

### Info Params

```
    --help                  print usage and exit
    --console <type>        set console output type, candidates: auto, rich, plain, default: auto
    --verbosity <level>     set logging verbosity, candidates: quiet, error, warn, lifecycle, info, debug, default: lifecycle
-v, --version               Jib CLI version information
```

### Debugging Params

```
    --stacktrace            print stacktrace on error (for debugging issues in the jib-cli)
    --http-trace            enable http tracing at level=config, output=console
    --serialize             run jib in serialized mode
```

## Global Jib Configuration

Some options can be set in the global Jib configuration file. The file is at the following locations on each platform:

* *Linux: `[config root]/google-cloud-tools-java/jib/config.json`, where `[config root]` is `$XDG_CONFIG_HOME` (`$HOME/.config/` if not set)*
* *Mac: `[config root]/Google/Jib/config.json`, where `[config root]` is `$XDG_CONFIG_HOME` (`$HOME/Library/Preferences/Config/` if not set)*
* *Windows: `[config root]\Google\Jib\Config\config.json`, where `[config root]` is `$XDG_CONFIG_HOME` (`%LOCALAPPDATA%` if not set)*

### Properties 

* `disableUpdateCheck`: when set to true, disables the periodic up-to-date version check.
* `registryMirrors`: a list of mirror settings for each base image registry. In the following example, if the base image configured in Jib is for a Docker Hub image, then `mirror.gcr.io`, `localhost:5000`, and the Docker Hub (`registry-1.docker.io`) are tried in order until Jib can successfully pull a base image.

```json
{
  "disableUpdateCheck": false,
  "registryMirrors": [
    {
      "registry": "registry-1.docker.io",
      "mirrors": ["mirror.gcr.io", "localhost:5000"]
    },
    {
      "registry": "quay.io",
      "mirrors": ["private-mirror.test.com"]
    }
  ]
}
```
**Note about `mirror.gcr.io`**: it is _not_ a Docker Hub mirror but a cache. It caches [frequently-accessed public Docker Hub images](https://cloud.google.com/container-registry/docs/pulling-cached-images), and it's often possible that your base image does not exist in `mirror.gcr.io`. In that case, Jib will have to fall back to use Docker Hub.

## References

### Fully Annotated Build File (`jib.yaml`)

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### Layers Behavior

- Copy directives are bound by the following rules
  `src`: filetype determined by type on local disk
   - if `src` is directory, `dest` is always considered a directory, directory and contents will be copied over and renamed to `dest`
   - if `src` is file
     - if `dest` ends with `/` then it is considered a target directory, file will be copied into directory
     - if `dest` doesn't end with `/` then is is the target file location, `src` file will be copied and renamed to `dest`
- Permissions for a file or directory that appear in multiple layers will prioritize the *last* layer and copy directive the file appears in. In the following example, `file.txt` as seen on the running container will have filePermissions `234`.
    ```
    - name: layer1
      properties:
        filePermissions: "123"
      - src: file.txt
        dest: /file.txt
    - name: layer2
      properties:
        filePermissions: "234"
      - src: file.txt
        dest: /file.txt
     ```
- Parent directories that are not explicitly defined in a layer will the default properties in jib-core (permissions: 755, modification-time: epoch+1). In the following example, `/somewhere` on the container will have the directory permissions `755`, not `777` as some might expect.
    ```
    - name: layer
      properties:
        directoryPermissions: "777"
      - src: file.txt
        dest: /somewhere/file.txt
    ```
- `excludes` on a directory can lead to unintended inclusion of files in the directory, to exclude a directory *and* all its files
     ```
     excludes:
       - "**/exclude-dir"
       - "**/exclude-dir/**
     ```
     
#### Base Image Parameter Inheritance

Some values defined in the base image may be preserved and propagated into the new container.

Parameters will append to base image value:
- `volumes`
- `exposedPorts`

Parameters that will append any new keys, and overwrite existing keys:
- `labels`
- `environment`

Parameters that will be overwritten:
- `user`
- `workingDirectory`
- `entrypoint`
- `cmd`

## Privacy

See the [Privacy page](https://github.com/GoogleContainerTools/jib/blob/master/docs/privacy.md).

## Disclaimer

This is not an officially supported Google product.

---

### Overview (`jib-core/README.md`)

[](https://maven-badges.herokuapp.com/maven-central/com.google.cloud.tools/jib-core)
[](https://gitter.im/google/jib)

# Jib Core - Java library for building containers

Jib Core is a Java library for building Docker and [OCI](https://github.com/opencontainers/image-spec) container images. It implements a general-purpose container builder that can be used to build containers without a Docker daemon, for any application. The implementation is pure Java.

*The API is currently in beta and may change substantially.*

Jib Core powers the popular Jib plugins for Maven and Gradle. The plugins build containers specifically for JVM languages and separate the application into multiple layers to optimize for fast rebuilds.\
For the Maven plugin, see the [jib-maven-plugin project](../jib-maven-plugin).\
For the Gradle plugin, see the [jib-gradle-plugin project](../jib-gradle-plugin).

For information about the Jib project, see the [Jib project README](../README.md).

## Adding Jib Core to your build

Add Jib Core as a dependency using Maven:

```xml
<dependency>
  <groupId>com.google.cloud.tools</groupId>
  <artifactId>jib-core</artifactId>
  <version>0.28.2</version>
</dependency>
```

Add Jib Core as a dependency using Gradle:

```groovy
dependencies {
  compile 'com.google.cloud.tools:jib-core:0.28.2'
}
```

## Examples

```java
Jib.from("busybox")
   .addLayer(Arrays.asList(Paths.get("helloworld.sh")), AbsoluteUnixPath.get("/")) 
   .setEntrypoint("sh", "/helloworld.sh")
   .containerize(
       Containerizer.to(RegistryImage.named("gcr.io/my-project/hello-from-jib")
                                     .addCredential("myusername", "mypassword")));
```

1. [`Jib.from("busybox")`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/Jib.html#from-java.lang.String-) creates a new [`JibContainerBuilder`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/0.1.0/com/google/cloud/tools/jib/api/JibContainerBuilder.html) configured with [`busybox`](https://hub.docker.com/_/busybox/) as the base image.
1. [`.addLayer(...)`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/JibContainerBuilder.html#addLayer-java.util.List-com.google.cloud.tools.jib.api.AbsoluteUnixPath-) configures the `JibContainerBuilder` with a new layer with `helloworld.sh` (local file) to be placed into the container at `/helloworld.sh`.
1. [`.setEntrypoint("sh", "/helloworld.sh")`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/JibContainerBuilder.html#setEntrypoint-java.lang.String...-) sets the entrypoint of the container to run `/helloworld.sh`.
1. [`RegistryImage.named("gcr.io/my-project/hello-from-jib")`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/RegistryImage.html#named-java.lang.String-) creates a new [`RegistryImage`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/RegistryImage.html) configured with `gcr.io/my-project/hello-from-jib` as the target image to push to.
1. [`.addCredential`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/RegistryImage.html#addCredential-java.lang.String-java.lang.String-) adds the username/password credentials to authenticate the push to `gcr.io/my-project/hello-from-jib`. See [`CredentialRetrieverFactory`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/frontend/CredentialRetrieverFactory.html) for common credential retrievers (to retrieve credentials from Docker config or credential helpers, for example). These credential retrievers can be used with [`.addCredentialRetriever`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/RegistryImage.html#addCredentialRetriever-com.google.cloud.tools.jib.api.CredentialRetriever-).
1. [`Containerizer.to`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/Containerizer.html#to-com.google.cloud.tools.jib.api.RegistryImage-) creates a new [`Containerizer`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/Containerizer.html) configured to push to the `RegistryImage`.
1. [`.containerize`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/JibContainerBuilder.html#containerize-com.google.cloud.tools.jib.api.Containerizer-) executes the containerization. If successful, the container image will be available at `gcr.io/my-project/hello-from-jib`.

See [examples](examples/README.md) for links to more jib-core samples. We welcome contributions for additional examples and tutorials!

## API overview

[`Jib`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/Jib.html) - the main entrypoint for using Jib Core

[`JibContainerBuilder`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/JibContainerBuilder.html) - configures the container to build

[`Containerizer`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/Containerizer.html) - configures how and where to containerize to

[`JibContainer`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/JibContainer.html) - information about the built container

Three types define what Jib can accept as either the base image or as the build target:
- [`RegistryImage`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/RegistryImage.html) - an image on a container registry
- [`DockerDaemonImage`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/DockerDaemonImage.html) - an image in the Docker daemon
- [`TarImage`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/TarImage.html) - an image saved as a tarball archive on the filesystem

Other useful classes:
- [`ImageReference`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/ImageReference.html) - represents an image reference and has useful methods for parsing and manipulating image references
- [`LayerConfiguration`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/LayerConfiguration.html) - configures a container layer to build
- [`CredentialRetriever`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/CredentialRetriever.html) - implement with custom credential retrieval methods for authenticating against a container registry
- [`CredentialRetrieverFactory`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/frontend/CredentialRetrieverFactory.html) - provides useful `CredentialRetriever`s to retrieve credentials from Docker config and credential helpers

Java-specific API:
- [`JavaContainerBuilder`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/JavaContainerBuilder.html) - configures a `JibContainerBuilder` for Java-specific applications
- [`MainClassFinder`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/MainClassFinder.html) - find the main Java class in a given list of class files

## API reference

[API reference](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/package-summary.html)

## How Jib Core works

The Jib Core system consists 3 main parts:

- an execution orchestrator that executes an asynchronous pipeline of containerization steps,
- an image manipulator capable of handling Docker and OCI image formats, and
- a registry client that implements the [Docker Registry V2 API](https://docs.docker.com/registry/spec/api/).

Some other parts of Jib Core internals include:

- a caching mechanism to speed up builds (configurable with [`Containerizer.setApplicationLayersCache`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/Containerizer.html#setApplicationLayersCache-java.nio.file.Path-) and [`Containerizer.setBaseImageLayersCache`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/Containerizer.html#setBaseImageLayersCache-java.nio.file.Path-))
- an [eventing system](#events) to react to events from Jib Core during its execution (add handlers with [`Containerizer.addEventHandler`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/Containerizer.html#addEventHandler-java.lang.Class-java.util.function.Consumer-))
- support for fully-concurrent multi-threaded executions

## Events

Throughout the build process, Jib Core dispatches events that provide useful information. These events implement the type [`JibEvent`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/JibEvent.html), and can be handled by registering event handlers with the containerizer.

```java
Jib.from(...)
    ...
    .containerize(
        Containerizer.to(...)
            ...
            .addEventHandler(LogEvent.class, logEvent -> System.out.println(logEvent.getLevel() + ": " + logEvent.getMessage())
            .addEventHandler(TimerEvent.class, timeEvent -> ...));
```

When Jib dispatches events, the event handlers you defined for that event type will be called. The following are the types of events you can listen for in Jib core (see [API reference](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/package-summary.html) for more information):

- [`LogEvent`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/api/LogEvent.html) - Log message events. The message and verbosity can be retrieved using `getMessage()` and `getLevel()`, respectively.
- [`TimerEvent`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/event/events/TimerEvent.html) (*Incubating*) - Events used for measuring how long different build steps take. You can retrieve the duration since the timer's creation and the duration since the same timer's previous event using `getElapsed()` and `getDuration()`, respectively.
- [`ProgressEvent`](http://www.javadoc.io/page/com.google.cloud.tools/jib-core/latest/com/google/cloud/tools/jib/event/events/ProgressEvent.html) (*Incubating*) - Indicates the amount of progress build steps have made. Each progress event consists of an allocation (containing a fraction representing how much of the root allocation this allocation accounts for) and a number of progress units that indicates the amount of work completed since the previous progress event. In other words, the amount of work a single progress event has completed (out of 1.0) can be calculated using `getAllocation().getFractionOfRoot() * getUnits()`.

## Frequently Asked Questions (FAQ)

See the [Jib project FAQ](../docs/faq.md).

## Upcoming features

- Extensions to make building Java and other language-specific containers easier

See [Milestones](https://github.com/GoogleContainerTools/jib/milestones) for planned features. [Get involved with the community](https://github.com/GoogleContainerTools/jib/tree/master#get-involved-with-the-community) for the latest updates.

## Community

See the [Jib project README](/../../#community).

---

### Overview (`jib-gradle-plugin/README.md`)

[](https://plugins.gradle.org/plugin/com.google.cloud.tools.jib)
[](https://gitter.im/google/jib)

# Jib - Containerize your Gradle Java project

Jib is a [Gradle](https://gradle.org/) plugin for building Docker and [OCI](https://github.com/opencontainers/image-spec) images for your Java applications.

For the Maven plugin, see the [jib-maven-plugin project](../jib-maven-plugin).

For information about the project, see the [Jib project README](../README.md).

| ☑️  Jib User Survey |
| :----- |
| What do you like best about Jib? What needs to be improved? Please tell us by taking a [one-minute survey](https://forms.gle/YRFeamGj51xmgnx28). Your responses will help us understand Jib usage and allow us to serve our customers (you!) better. |

## Table of Contents

* [Upcoming Features](#upcoming-features)
* [Quickstart](#quickstart)
  * [Setup](#setup)
  * [Configuration](#configuration)
  * [Build your image](#build-your-image)
    * [Build to Docker Daemon](#build-to-docker-daemon)
    * [Build an image tarball](#build-an-image-tarball)
  * [Run `jib` with each build](#run-jib-with-each-build)
  * [Additional Build Artifacts](#additional-build-artifacts)
* [Multi Module Projects](#multi-module-projects)
* [Extended Usage](#extended-usage)
  * [System Properties](#system-properties)
  * [Global Jib Configuration](#global-jib-configuration)
  * [Example](#example)
  * [Adding Arbitrary Files to the Image](#adding-arbitrary-files-to-the-image)
  * [Authentication Methods](#authentication-methods)
    * [Using Docker configuration files](#using-docker-configuration-files)
    * [Using Docker Credential Helpers](#using-docker-credential-helpers)
    * [Using Specific Credentials](#using-specific-credentials)
  * [Custom Container Entrypoint](#custom-container-entrypoint)
  * [Reproducible Build Timestamps](#reproducible-build-timestamps)
  * [Jib Extensions](#jib-extensions)
  * [WAR Projects](#war-projects)
  * [Skaffold Integration](#skaffold-integration)
* [Need Help?](#need-help)
* [Community](#community)

## Quickstart

### Setup

*Make sure you are using Gradle version 5.1 or later.*

In your Gradle Java project, add the plugin to your `build.gradle`:

```groovy
plugins {
  id 'com.google.cloud.tools.jib' version '3.5.4'
}
```

*See the [Gradle Plugin Portal](https://plugins.gradle.org/plugin/com.google.cloud.tools.jib) for more details.*

You can containerize your application easily with one command:

```shell
gradle jib --image=<MY IMAGE>
```

This builds and pushes a container image for your application to a container registry. *If you encounter authentication issues, see [Authentication Methods](#authentication-methods).*

To build to a Docker daemon, use:

```shell
gradle jibDockerBuild
```

If you would like to set up Jib as part of your Gradle build, follow the guide below.

## Configuration

Configure the plugin by setting the image to push to:

#### Using [Google Container Registry (GCR)](https://cloud.google.com/container-registry/)...

*Make sure you have the [`docker-credential-gcr` command line tool](https://cloud.google.com/container-registry/docs/advanced-authentication#docker_credential_helper). Jib automatically uses `docker-credential-gcr` for obtaining credentials. See [Authentication Methods](#authentication-methods) for other ways of authenticating.*

For example, to build the image `gcr.io/my-gcp-project/my-app`, the configuration would be:

```groovy
jib.to.image = 'gcr.io/my-gcp-project/my-app'
```

#### Using [Amazon Elastic Container Registry (ECR)](https://aws.amazon.com/ecr/)...

*Make sure you have the [`docker-credential-ecr-login` command line tool](https://github.com/awslabs/amazon-ecr-credential-helper). Jib automatically uses `docker-credential-ecr-login` for obtaining credentials. See [Authentication Methods](#authentication-methods) for other ways of authenticating.*

For example, to build the image `aws_account_id.dkr.ecr.region.amazonaws.com/my-app`, the configuration would be:

```groovy
jib.to.image = 'aws_account_id.dkr.ecr.region.amazonaws.com/my-app'
```

#### Using [Docker Hub Registry](https://hub.docker.com/)...

*Make sure you have a [docker-credential-helper](https://github.com/docker/docker-credential-helpers#available-programs) set up. For example, on macOS, the credential helper would be `docker-credential-osxkeychain`. See [Authentication Methods](#authentication-methods) for other ways of authenticating.*

For example, to build the image `my-docker-id/my-app`, the configuration would be:

```groovy
jib.to.image = 'my-docker-id/my-app'
```

#### Using [JFrog Container Registry (JCR)](https://jfrog.com/container-registry) or [JFrog Artifactory](https://jfrog.com/help/r/jfrog-artifactory-documentation/getting-started-with-artifactory-as-a-docker-registry)...

*Make sure you have a [docker-credential-helper](https://github.com/docker/docker-credential-helpers#available-programs) set up. For example, on macOS, the credential helper would be `docker-credential-osxkeychain`. See [Authentication Methods](#authentication-methods) for other ways of authenticating.*

For example, to build the image `my-company-docker-local.jfrog.io/my-app`, the configuration would be:

```groovy
jib.to.image = 'my-company-docker-local.jfrog.io/my-app'
```

#### Using [Azure Container Registry (ACR)](https://azure.microsoft.com/en-us/services/container-registry/)...

*Make sure you have a [`ACR Docker Credential Helper`](https://github.com/Azure/acr-docker-credential-helper) installed and set up. For example, on Windows, the credential helper would be `docker-credential-acr-windows`. See [Authentication Methods](#authentication-methods) for other ways of authenticating.*

For example, to build the image `my_acr_name.azurecr.io/my-app`, the configuration would be:

```groovy
jib.to.image = 'my_acr_name.azurecr.io/my-app'
```

### Build Your Image

Build your container image with:

```shell
gradle jib
```

Subsequent builds are much faster than the initial build.

*Having trouble? Let us know by [submitting an issue](/../../issues/new), contacting us on [Gitter](https://gitter.im/google/jib), or posting to the [Jib users forum](https://groups.google.com/forum/#!forum/jib-users).*

#### Build to Docker daemon

Jib can also build your image directly to a Docker daemon. This uses the `docker` command line tool and requires that you have `docker` available on your `PATH`.

```shell
gradle jibDockerBuild
```

If you are using [`minikube`](https://github.com/kubernetes/minikube)'s remote Docker daemon, make sure you [set up the correct environment variables](https://minikube.sigs.k8s.io/docs/handbook/pushing/#1-pushing-directly-to-the-in-cluster-docker-daemon-docker-env) to point to the remote daemon:

```shell
eval $(minikube docker-env)
gradle jibDockerBuild
```

Alternatively, you can set environment variables in the Jib configuration. See [`dockerClient`](#dockerclient-closure) for more configuration options.

#### Build an image tarball

You can build and save your image to disk as a tarball with:

```shell
gradle jibBuildTar
```

This builds and saves your image to `build/jib-image.tar`, which you can load into docker with:

```shell
docker load --input build/jib-image.tar
```

### Run `jib` with each build

You can also have `jib` run with each build by attaching it to the `build` task:

```groovy
tasks.build.dependsOn tasks.jib
```

Then, ```gradle build``` will build and containerize your application.

### Additional Build Artifacts

As part of an image build, Jib also writes out the _image digest_ and the _image ID_. By default, these are written out to `build/jib-image.digest` and `build/jib-image.id` respectively, but the locations can be configured using the `jib.outputPaths.digest` and `jib.outputPaths.imageId` configuration properties. See [Extended Usage](#outputpaths-closure) for more details.

## Multi Module Projects

Special handling of project dependencies is recommended when building complex
multi module projects. See [Multi Module Example](https://github.com/GoogleContainerTools/jib/tree/master/examples/multi-module) for detailed information.

## Extended Usage

The plugin provides the `jib` extension for configuration with the following options for customizing the image build:

Field | Type | Default | Description
--- | --- | --- | ---
`to` | [`to`](#to-closure) | *Required* | Configures the target image to build your application to.
`from` | [`from`](#from-closure) | See [`from`](#from-closure) | Configures the base image to build your application on top of.
`container` | [`container`](#container-closure) | See [`container`](#container-closure) | Configures the container that is run from your built image.
`extraDirectories` | [`extraDirectories`](#extradirectories-closure) | See [`extraDirectories`](#extradirectories-closure) | Configures the directories used to add arbitrary files to the image.
`outputPaths` | [`outputPaths`](#outputpaths-closure) | See [`outputPaths`](#outputpaths-closure) | Configures the locations of additional build artifacts generated by Jib.
`dockerClient` | [`dockerClient`](#dockerclient-closure) | See [`dockerClient`](#dockerclient-closure) | Configures Docker for building to/from the Docker daemon.
`skaffold` | [`skaffold`](#skaffold-integration) | See [`skaffold`](#skaffold-integration) | Configures the internal skaffold tasks. This configuration should only be used when integrating with [`skaffold`](#skaffold-integration). |
`containerizingMode` | `String` | `exploded` | If set to `packaged`, puts the JAR artifact built by the Gradle Java plugin into the final image. If set to `exploded` (default), containerizes individual `.class` files and resources files.
`allowInsecureRegistries` | `boolean` | `false` | If set to true, Jib ignores HTTPS certificate errors and may fall back to HTTP as a last resort. Leaving this parameter set to `false` is strongly recommended, since HTTP communication is unencrypted and visible to others on the network, and insecure HTTPS is no better than plain HTTP. [If accessing a registry with a self-signed certificate, adding the certificate to your Java runtime's trusted keys](https://github.com/GoogleContainerTools/jib/tree/master/docs/self_sign_cert.md) may be an alternative to enabling this option.
`configurationName` | `String` | `runtimeClasspath` | Specify the name of the [Gradle Configuration](https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.ConfigurationContainer.html) to use.

<a name="from-closure"></a>`from` is a closure with the following properties:

Property | Type | Default                                                    | Description
--- | --- |------------------------------------------------------------| ---
`image` | `String` | `eclipse-temurin:{8,11,17,21,25}-jre` (or `jetty` for WAR) | The image reference for the base image. The source type can be specified using a [special type prefix](#setting-the-base-image).
`auth` | [`auth`](#auth-closure) | *None*                                                     | Specifies credentials directly (alternative to `credHelper`).
`credHelper` | `String` | *None*                                                     | Specifies a credential helper that can authenticate pulling the base image. This parameter can either be configured as an absolute path to the credential helper executable or as a credential helper suffix (following `docker-credential-`).
`platforms` | [`platforms`](#platforms-closure) | See [`platforms`](#platforms-closure)                      | Configures platforms of base images to select from a manifest list.

<a name="to-closure"></a>`to` is a closure with the following properties:

Property | Type | Default | Description
--- | --- | --- | ---
`image` | `String` | *Required* | The image reference for the target image. This can also be specified via the `--image` command line option. If the tag is not present here `:latest` is implied.
`auth` | [`auth`](#auth-closure) | *None* | Specifies credentials directly (alternative to `credHelper`).
`credHelper` | `String` | *None* | Specifies a credential helper that can authenticate pushing the target image. This parameter can either be configured as an absolute path to the credential helper executable or as a credential helper suffix (following `docker-credential-`).
`tags` | `List<String>` | *None* | Additional tags to push to.

<a name="auth-closure"></a>`auth` is a closure with the following properties (see [Using Specific Credentials](#using-specific-credentials)):

Property | Type
--- | ---
`username` | `String`
`password` | `String`

<a name="platforms-closure"></a>`platforms` can configure multiple `platform` closures.  Each individual `platform` has the following properties:

Property | Type | Default | Description
--- | --- | --- | ---
`architecture` | `String` | `amd64` | The architecture of a base image to select from a manifest list.
`os` | `String` | `linux` | The OS of a base image to select from a manifest list.

See [How do I specify a platform in the manifest list (or OCI index) of a base image?](../docs/faq.md#how-do-i-specify-a-platform-in-the-manifest-list-or-oci-index-of-a-base-image) for examples.

<a name="container-closure"></a>`container` is a closure with the following properties:

Property | Type | Default | Description
--- | --- | --- | ---
`appRoot` | `String` | `/app` | The root directory on the container where the app's contents are placed. Particularly useful for WAR-packaging projects to work with different Servlet engine base images by designating where to put exploded WAR contents; see [WAR usage](#war-projects) as an example.
`args` | `List<String>` | *None* | Additional program arguments appended to the command to start the container (similar to Docker's [CMD](https://docs.docker.com/engine/reference/builder/#cmd) instruction in relation with [ENTRYPOINT](https://docs.docker.com/engine/reference/builder/#entrypoint)). In the default case where you do not set a custom `entrypoint`, this parameter is effectively the arguments to the main method of your Java application.
`creationTime` | `String` | `EPOCH` | Sets the container creation time. (Note that this property does not affect the file modification times, which are configured using `jib.container.filesModificationTime`.) The value can be `EPOCH` to set the timestamps to Epoch (default behavior), `USE_CURRENT_TIMESTAMP` to forgo reproducibility and use the real creation time, or an ISO 8601 date-time parsable with [`DateTimeFormatter.ISO_DATE_TIME`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/DateTimeFormatter.html#ISO_DATE_TIME) such as `2019-07-15T10:15:30+09:00` or `2011-12-03T22:42:05Z`. The value can also be initialized [lazily](https://docs.gradle.org/current/userguide/lazy_configuration.html) with a provider.
`entrypoint` | `List<String>` | *None* | The command to start the container with (similar to Docker's [ENTRYPOINT](https://docs.docker.com/engine/reference/builder/#entrypoint) instruction). If set, then `jvmFlags`, `mainClass`, `extraClasspath`, and `expandClasspathDependencies` are ignored. You may also set `jib.container.entrypoint = 'INHERIT'` to indicate that the `entrypoint` and `args` should be inherited from the base image.\* The value can also be initialized [lazily](https://docs.gradle.org/current/userguide/lazy_configuration.html) with a provider.
`environment` | `Map<String, String>` | *None* | Key-value pairs for setting environment variables on the container (similar to Docker's [ENV](https://docs.docker.com/engine/reference/builder/#env) instruction).
`extraClasspath` | `List<String>` | *None* | Additional paths in the container to prepend to the computed Java classpath.
`expandClasspathDependencies` | `boolean` | `false` | <ul><li>Java 8 *or* Jib < 3.1: When set to true, does not use a wildcard (for example, `/app/lib/*`) for dependency JARs in the default Java runtime classpath but instead enumerates the JARs. Has the effect of preserving the classpath loading order as defined by the Gradle project.</li><li>Java >= 9 *and* Jib >= 3.1: The option has no effect. Jib *always* enumerates the dependency JARs. This is achieved by [creating and using an argument file](#custom-container-entrypoint) for the `--class-path` JVM argument.</li></ul>
`filesModificationTime` | `String` | `EPOCH_PLUS_SECOND` | Sets the modification time (last modified time) of files in the image put by Jib. (Note that this does not set the image creation time, which can be set using `jib.container.creationTime`.) The value should either be `EPOCH_PLUS_SECOND` to set the timestamps to Epoch + 1 second (default behavior), or an ISO 8601 date-time parsable with [`DateTimeFormatter.ISO_DATE_TIME`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/DateTimeFormatter.html#ISO_DATE_TIME) such as `2019-07-15T10:15:30+09:00` or `2011-12-03T22:42:05Z`. The value can also be initialized [lazily](https://docs.gradle.org/current/userguide/lazy_configuration.html) with a provider.
`format` | `String` | `Docker` | Use `OCI` to build an [OCI container image](https://www.opencontainers.org/).
`jvmFlags` | `List<String>` | *None* | Additional flags to pass into the JVM when running your application. The value can also be initialized [lazily](https://docs.gradle.org/current/userguide/lazy_configuration.html) with a provider.
`labels` | `Map<String, String>` | *None* | Key-value pairs for applying image metadata (similar to Docker's [LABEL](https://docs.docker.com/engine/reference/builder/#label) instruction).
`mainClass` | `String` | *Inferred*\*\* | The main class to launch your application from. The value can also be initialized [lazily](https://docs.gradle.org/current/userguide/lazy_configuration.html) with a provider.
`ports` | `List<String>` | *None* | Ports that the container exposes at runtime (similar to Docker's [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose) instruction).
`user` | `String` | *None* | The user and group to run the container as. The value can be a username or UID along with an optional groupname or GID. The following are all valid: `user`, `uid`, `user:group`, `uid:gid`, `uid:group`, `user:gid`.
`volumes` | `List<String>` | *None* | Specifies a list of mount points on the container.
`workingDirectory` | `String` | *None* | The working directory in the container.

<a name="extradirectories-closure"></a>`extraDirectories` is a closure with the following properties (see [Adding Arbitrary Files to the Image](#adding-arbitrary-files-to-the-image)):

Property | Type | Default | Description
--- | --- | --- | ---
`paths` | [`paths`](#paths-closure) closure, or `Object` | `(project-dir)/src/main/jib` | May be configured as a closure configuring `path` elements, or as source directory values recognized by [`Project.files()`](https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html#files-java.lang.Object...-), such as `String`, `File`, `Path`, `List<String\|File\|Path>`, etc.
`permissions` | `Map<String, String>` | *None* | Maps file paths (glob patterns) on container to Unix permissions. (Effective only for files added from extra directories.) If not configured, permissions default to "755" for directories and "644" for files. See [Adding Arbitrary Files to the Image](#adding-arbitrary-files-to-the-image) for an example.

<a name="paths-closure"></a>`paths` can configure multiple `path` closures (see [Adding Arbitrary Files to the Image](#adding-arbitrary-files-to-the-image)). Each individual `path` has the following properties:

Property | Type | Default | Description
--- | --- | --- | ---
`from` | `Object` | `(project-dir)/src/main/jib` | Accepts source directories that are recognized by [`Project.files()`](https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html#files-java.lang.Object...-), such as `String`, `File`, `Path`, `List<String\|File\|Path>`, etc.
`into` | `String` | `/` | The absolute unix path on the container to copy the extra directory contents into.
`includes` | `List<String>` | *None* | Glob patterns for including files. See [Adding Arbitrary Files to the Image](#adding-arbitrary-files-to-the-image) for an example.
`excludes` | `List<String>` | *None* | Glob patterns for excluding files. See [Adding Arbitrary Files to the Image](#adding-arbitrary-files-to-the-image) for an example.

<a name="outputpaths-closure"></a>`outputPaths` is a closure with the following properties:

Property | Type | Default | Description
--- | --- | --- | ---
`tar` | `File` | `(project-dir)/build/jib-image.tar` | The path of the tarball generated by `jibBuildTar`. Relative paths are resolved relative to the project root.
`digest` | `File` | `(project-dir)/build/jib-image.digest` | The path of the image digest written out during the build. Relative paths are resolved relative to the project root.
`imageId` | `File` | `(project-dir)/build/jib-image.id` | The path of the image ID written out during the build. Relative paths are resolved relative to the project root.

<a name="dockerclient-closure"></a>`dockerClient` is an object used to configure Docker when building to/from the Docker daemon. It has the following properties:

Property | Type | Default | Description
--- | --- | --- | ---
`executable` | `File` | `docker` | Sets the path to the Docker executable that is called to load the image into the Docker daemon. **Please note**: Users are responsible for ensuring that the Docker path passed in is valid and has the right permissions to be executed.
`environment` | `Map<String, String>` | *None* | Sets environment variables used by the Docker executable.

#### System Properties

Each of these parameters is configurable via commandline using system properties. Jib's system properties follow the same naming convention as the configuration parameters, with each level separated by dots (i.e. `-Djib.parameterName[.nestedParameter.[...]]=value`). Some examples are below:
```shell
gradle jib \
    -Djib.to.image=myregistry/myimage:latest \
    -Djib.to.auth.username=$USERNAME \
    -Djib.to.auth.password=$PASSWORD

gradle jibDockerBuild \
    -Djib.dockerClient.executable=/path/to/docker \
    -Djib.container.environment=key1="value1",key2="value2" \
    -Djib.container.args=arg1,arg2,arg3
```

The following table contains additional system properties that are not available as build configuration parameters:

Property | Type | Default | Description
--- | --- | --- | ---
`jib.httpTimeout` | `int` | `20000` | HTTP connection/read timeout for registry interactions, in milliseconds. Use a value of `0` for an infinite timeout.
`jib.useOnlyProjectCache` | `boolean` | `false` | If set to true, Jib does not share a cache between different Gradle projects.
`jib.baseImageCache` | `File` | *Platform-dependent*\*\*\* | Sets the directory to use for caching base image layers. This cache can (and should) be shared between multiple images.
`jib.applicationCache` | `File` | `[project dir]/build/jib-cache` | Sets the directory to use for caching application layers. This cache can be shared between multiple images.
`jib.console` | `String` | *None* | If set to `plain`, Jib will print plaintext log messages rather than display a progress bar during the build.

*\* If you configure `args` while `entrypoint` is set to `'INHERIT'`, the configured `args` value will take precedence over the CMD propagated from the base image.*

*\*\* Uses the main class defined in the `jar` task or tries to find a valid main class.*

*\*\*\* The default base image cache is in the following locations on each platform:*
 * *Linux: `[cache root]/google-cloud-tools-java/jib/`, where `[cache root]` is `$XDG_CACHE_HOME` (`$HOME/.cache/` if not set)*
 * *Mac: `[cache root]/Google/Jib/`, where `[cache root]` is `$XDG_CACHE_HOME` (`$HOME/Library/Caches/` if not set)*
 * *Windows: `[cache root]\Google\Jib\Cache`, where `[cache root]` is `%XDG_CACHE_HOME%` (`%LOCALAPPDATA%` if not set)*

### Global Jib Configuration

Some options can be set in the global Jib configuration file. The file is at the following locations on each platform:

* *Linux: `[config root]/google-cloud-tools-java/jib/config.json`, where `[config root]` is `$XDG_CONFIG_HOME` (`$HOME/.config/` if not set)*
* *Mac: `[config root]/Google/Jib/config.json`, where `[config root]` is `$XDG_CONFIG_HOME` (`$HOME/Library/Preferences/Config/` if not set)*
* *Windows: `[config root]\Google\Jib\Config\config.json`, where `[config root]` is `%XDG_CONFIG_HOME%` (`%LOCALAPPDATA%` if not set)*

#### Properties

* `disableUpdateCheck`: when set to true, disables the periodic up-to-date version check.
* `registryMirrors`: a list of mirror settings for each base image registry. In the following example, if the base image configured in Jib is for a Docker Hub image, then `mirror.gcr.io`, `localhost:5000`, and the Docker Hub (`registry-1.docker.io`) are tried in order until Jib can successfully pull a base image.

```json
{
  "disableUpdateCheck": false,
  "registryMirrors": [
    {
      "registry": "registry-1.docker.io",
      "mirrors": ["mirror.gcr.io", "localhost:5000"]
    },
    {
      "registry": "quay.io",
      "mirrors": ["private-mirror.test.com"]
    }
  ]
}
```
**Note about `mirror.gcr.io`**: it is _not_ a Docker Hub mirror but a cache. It caches [frequently-accessed public Docker Hub images](https://cloud.google.com/container-registry/docs/pulling-cached-images), and it's often possible that your base image does not exist in `mirror.gcr.io`. In that case, Jib will have to fall back to use Docker Hub.

### Example

In this configuration, the image:
* Is built from a base of `openjdk:alpine` (pulled from Docker Hub)
* Is pushed to `localhost:5000/my-image:built-with-jib`, `localhost:5000/my-image:tag2`, and `localhost:5000/my-image:latest`
* Runs by calling `java -Dmy.property=example.value -Xms512m -Xdebug -cp app/libs/*:app/resources:app/classes mypackage.MyApp some args`
* Exposes port 1000 for tcp (default), and ports 2000, 2001, 2002, and 2003 for udp
* Has two labels (key1:value1 and key2:value2)
* Is built as OCI format

```groovy
jib {
  from {
    image = 'openjdk:alpine'
  }
  to {
    image = 'localhost:5000/my-image/built-with-jib'
    credHelper = 'osxkeychain'
    tags = ['tag2', 'latest']
  }
  container {
    jvmFlags = ['-Dmy.property=example.value', '-Xms512m', '-Xdebug']
    mainClass = 'mypackage.MyApp'
    args = ['some', 'args']
    ports = ['1000', '2000-2003/udp']
    labels = [key1:'value1', key2:'value2']
    format = 'OCI'
  }
}
```

### Setting the Base Image

There are three different types of base images that Jib accepts: an image from a container registry, an image stored in the Docker daemon, or an image tarball on the local filesystem. You can specify which you would like to use by prepending the `jib.from.image` configuration with a special prefix, listed below:

Prefix | Example | Type
--- | --- | ---
*None* | `openjdk:11-jre` | Pulls the base image from a registry.
`registry://` | `registry://eclipse-temurin:11-jre` | Pulls the base image from a registry.
`docker://` | `docker://busybox` | Retrieves the base image from the Docker daemon.
`tar://` | `tar:///path/to/file.tar` | Uses an image tarball stored at the specified path as the base image. Also accepts relative paths (e.g. `tar://build/jib-image.tar`).

### Adding Arbitrary Files to the Image

You can add arbitrary, non-classpath files to the image without extra configuration by placing them in a `src/main/jib` directory. This will copy all files within the `jib` folder to the target directory (`/` by default) in the image, maintaining the same structure (e.g. if you have a text file at `src/main/jib/dir/hello.txt`, then your image will contain `/dir/hello.txt` after being built with Jib).

Note that Jib does not follow symbolic links in the container image.  If a symbolic link is present, _it will be removed_ prior to placing the files and directories.

You can configure different directories by using the `jib.extraDirectories.paths` parameter in your `build.gradle`:
```groovy
jib {
  // Copies files from 'src/main/custom-extra-dir' and '/home/user/jib-extras' instead of 'src/main/jib'
  extraDirectories.paths = ['src/main/custom-extra-dir', '/home/user/jib-extras']
}
```

Alternatively, the `jib.extraDirectories` parameter can be used as a closure to set custom extra directories, as well as the extra files' permissions on the container:

```groovy
jib {
  extraDirectories {
    paths = 'src/main/custom-extra-dir'  // Copies files from 'src/main/custom-extra-dir'
    permissions = [
        '/path/on/container/to/fileA': '755',  // Read/write/execute for owner, read/execute for group/other
        '/path/to/another/file': '644',  // Read/write for owner, read-only for group/other
        '/glob/pattern/**/*.sh': 755
    ]
  }
}
```

Using `paths` as a closure, you may also specify the target of the copy and include or exclude files:

```groovy
  extraDirectories {
    paths {
      path {
        // copies the contents of 'src/main/extra-dir' into '/' on the container
        from = file('src/main/extra-dir')
      }
      path {
        // copies the contents of 'src/main/another/dir' into '/extras' on the container
        from = file('src/main/another/dir')
        into = '/extras'
      }
      path {
        // copies a single-file.xml
        from = 'src/main/resources/xml-files'
        into = '/dest-in-container'
        includes = ['single-file.xml']
      }
      path {
        // copies only .txt files except for 'hidden.txt' at the source root
        from = 'build/some-output'
        into = '/txt-files'
        includes = ['*.txt', '**/*.txt']
        excludes = ['hidden.txt']
      }
    }
  }
```

You can also configure `paths` and `permissions` through [lazy configuration in Gradle](https://docs.gradle.org/current/userguide/lazy_configuration.html), using providers in `build.gradle`:

```groovy
extraDirectories {
   paths = project.provider { 'src/main/custom-extra-dir' }
   permissions = project.provider { ['/path/on/container/to/fileA': '755'] }
}
```

```groovy
extraDirectories {
   paths {
     path { 
       from = project.provider { 'src/main/custom-extra-dir' }
       into = project.provider { '/dest-in-container' }
       includes = project.provider { ['*.txt', '**/*.txt'] }
       excludes = project.provider { ['hidden.txt'] }
    }
  }
}
```

### Authentication Methods

Pushing/pulling from private registries require authorization credentials.

#### Using Docker configuration files

* Jib looks from credentials from `$XDG_RUNTIME_DIR/containers/auth.json`, `$XDG_CONFIG_HOME/containers/auth.json`, `$HOME/.config/containers/auth.json`, `$DOCKER_CONFIG/config.json`, and `$HOME/.docker/config.json`.

See [this issue](/../../issues/101) and [`man containers-auth.json`](https://www.mankier.com/5/containers-auth.json) for more information about the files.

#### Using Docker Credential Helpers

Docker credential helpers are CLI tools that handle authentication with various registries.

Some common credential helpers include:

* Google Container Registry: [`docker-credential-gcr`](https://cloud.google.com/container-registry/docs/advanced-authentication#docker_credential_helper)
* AWS Elastic Container Registry: [`docker-credential-ecr-login`](https://github.com/awslabs/amazon-ecr-credential-helper)
* Docker Hub Registry: [`docker-credential-*`](https://github.com/docker/docker-credential-helpers)
* Azure Container Registry: [`docker-credential-acr-*`](https://github.com/Azure/acr-docker-credential-helper)

Configure credential helpers to use by specifying them as a `credHelper` for their respective image in the `jib` extension.

*Example configuration:*
```groovy
jib {
  from {
    image = 'aws_account_id.dkr.ecr.region.amazonaws.com/my-base-image'
    credHelper = 'ecr-login'
  }
  to {
    image = 'gcr.io/my-gcp-project/my-app'
    credHelper = 'gcr'
  }
}
```

#### Using Specific Credentials

You can specify credentials directly in the extension for the `from` and/or `to` images.

```groovy
jib {
  from {
    image = 'aws_account_id.dkr.ecr.region.amazonaws.com/my-base-image'
    auth {
      username = USERNAME // Defined in 'gradle.properties'.
      password = PASSWORD
    }
  }
  to {
    image = 'gcr.io/my-gcp-project/my-app'
    auth {
      username = 'oauth2accesstoken'
      password = 'gcloud auth print-access-token'.execute().text.trim()
    }
  }
}
```

These credentials can be stored in `gradle.properties`, retrieved from a command (like `gcloud auth print-access-token`), or read in from a file.

For example, you can use a key file for authentication (for GCR, see [Using a JSON key file](https://cloud.google.com/container-registry/docs/advanced-authentication#using_a_json_key_file)):

```groovy
jib {
  to {
    image = 'gcr.io/my-gcp-project/my-app'
    auth {
      username = '_json_key'
      password = file('keyfile.json').text
    }
  }
}
```


### Custom Container Entrypoint

If you don't set `jib.container.entrypoint`, the default container entrypoint to launch your app will be basically `java -cp <runtime classpath> <app main class>`. (The final `java` command can be further configured by setting `jib.container.{jvmFlags|args|extraClasspath|mainClass|expandClasspathDependencies}`.)

Sometimes, you'll want to set a custom entrypoint to use a shell to wrap the `java` command. For example, to let `sh` or `bash` [expand environment variables](https://stackoverflow.com/a/59361658/1701388), or to have more sophisticated logic to construct a launch command. (Note, however, that running a command with a shell forks a new child process unless you run it with `exec` like `sh -c "exec java ..."`. Whether to run the JVM process as PID 1 or a child process of a PID-1 shell is a [decision you should make carefully](https://github.com/GoogleContainerTools/distroless/issues/550#issuecomment-791610603).) In this scenario, you will want to have a way inside a shell script to reliably know the default runtime classpath and the main class that Jib would use by default. To help this, Jib >= 3.1 creates two JVM argument files under `/app` (the default app root) inside the built image.

- `/app/jib-classpath-file`: runtime classpath that Jib would use for default app launch
- `/app/jib-main-class-file`: main class

Therefore, *for example*, the following commands will be able to launch your app:

- (Java 9+) `java -cp @/app/jib-classpath-file @/app/jib-main-class-file`
- (with shell) `java -cp $( cat /app/jib-classpath-file ) $( cat /app/jib-main-class-file )`

### Reproducible Build Timestamps

To ensure that a Jib build is reproducible, Jib sets the image creation time to the Unix epoch (00:00:00, January 1st, 1970 in UTC) and all file modification times to one second past the epoch by default. See the [Jib FAQ](https://github.com/GoogleContainerTools/jib/blob/master/docs/faq.md#why-is-my-image-created-48-years-ago) for more details on reproducible builds.

Another, more complex way to achieve reproducible builds with stable creation times is to leverage commit timestamps from the project's SCM. For example, the [gradle-git-properties](https://plugins.gradle.org/plugin/com.gorylenko.gradle-git-properties) plugin can be used to inject Git commit information into the current build. These can then be used to configure `jib.container.creationTime`. Since the actual Git information is not yet available at the time the build is configured, it needs to be set through [lazy configuration in Gradle](https://docs.gradle.org/current/userguide/lazy_configuration.html), using a provider in `build.gradle`:

```groovy
jib {
   container {
     creationTime = project.provider { project.ext.git['git.commit.time'] }
   }
}
```

This would build an image with the creation time set to the time of the latest commit from `project.ext.git['git.commit.time']`.

### Jib Extensions

The Jib build plugins have an extension framework that enables anyone to easily extend Jib's behavior to their needs. We maintain select [first-party](https://github.com/GoogleContainerTools/jib-extensions/tree/master/first-party) plugins for popular use cases like [fine-grained layer control](https://github.com/GoogleContainerTools/jib-extensions/tree/master/first-party/jib-layer-filter-extension-gradle) and [Quarkus support](https://github.com/GoogleContainerTools/jib-extensions/tree/master/first-party/jib-quarkus-extension-gradle), but anyone can write and publish an extension. Check out the [jib-extensions](https://github.com/GoogleContainerTools/jib-extensions) repository for more information.


### WAR Projects

Jib also containerizes WAR projects. If the Gradle project uses the [WAR Plugin](https://docs.gradle.org/current/userguide/war_plugin.html), Jib will by default use [`jetty`](https://hub.docker.com/_/jetty) as a base image to deploy the project WAR. No extra configuration is necessary other than using the WAR Plugin to make Jib build WAR images.

Note that Jib will work slightly differently for WAR projects from JAR projects:
   - `container.mainClass` and `container.jvmFlags` are ignored.
   - The WAR will be exploded into `/var/lib/jetty/webapps/ROOT`, which is the expected WAR location for the Jetty base image.

To use a different Servlet engine base image, you can customize `container.appRoot`, `container.entrypoint`, and `container.args`. If you do not set `entrypoint` or `args`, Jib will inherit the `ENTRYPOINT` and `CMD` of the base image, so in many cases, you may not need to configure them. However, you will most likely have to set `container.appRoot` to a proper location depending on the base image. Here is an example of using a Tomcat image:

```gradle
jib {
  from.image = 'tomcat:8.5-jre8-alpine'

  // For demonstration only: this directory in the base image contains a Tomcat default
  // app (welcome page), so you may first want to delete this directory in the base image.
  container.appRoot = '/usr/local/tomcat/webapps/ROOT'
}
```
When specifying a [`jetty`](https://hub.docker.com/_/jetty) image yourself with `from.image`, you may run into an issue ([#3204](https://github.com/GoogleContainerTools/jib/issues/3204)) and need to override the entrypoint.
```gradle
jib {
  from.image = 'jetty:11.0.2-jre11'
  container.entrypoint = ['java', '-jar', '/usr/local/jetty/start.jar']
}
```


### Skaffold Integration

Jib is an included builder in [Skaffold](https://github.com/GoogleContainerTools/skaffold). Jib passes build information to skaffold through special internal tasks so that skaffold understands when it should rebuild or synchronize files. For complex builds, the defaults may not be sufficient, so the `jib` extension provides a `skaffold` configuration closure which exposes:

Field | Type | Default | Description
--- | --- | --- | ---
`watch` | [`watch`](#skaffold-watch-closure) | *None* | Additional configuration for file watching
`sync` | [`sync`](#skaffold-sync-closure) | *None* | Additional configuration for file synchronization

<a name="skaffold-watch-closure"></a>`watch` is a closure with the following properties:

Field | Type | Default | Description
--- | --- | --- | ---
`buildIncludes` | `List<String>` | *None* | Additional build files that skaffold should watch
`includes` | `List<String>` | *None* | Additional project files or directories that skaffold should watch
`excludes` | `List<String>` | *None* | Files and directories that skaffold should not watch

<a name="skaffold-sync-closure"></a>`sync` is a closure with the following properties:

Field | Type | Default | Description
--- | --- | --- | ---
`excludes` | `List<String>` | *None* | Files and directories that skaffold should not sync

## <a name=frequently-asked-questions-faq></a>Need Help?

A lot of questions are already answered!

* [Frequently Asked Questions (FAQ)](../docs/faq.md)
* [Stack Overflow](https://stackoverflow.com/questions/tagged/jib)
* [GitHub issues](https://github.com/GoogleContainerTools/jib/issues)

_For usage questions, please ask them on Stack Overflow._

## Privacy

See the [Privacy page](docs/privacy.md).

## Upcoming Features

See [Milestones](https://github.com/GoogleContainerTools/jib/milestones) for planned features. [Get involved with the community](https://github.com/GoogleContainerTools/jib/tree/master#get-involved-with-the-community) for the latest updates.

## Community

See the [Jib project README](/../../#community).

## Disclaimer

This is not an officially supported Google product.

---

### Overview (`jib-maven-plugin/README.md`)

[](https://maven-badges.herokuapp.com/maven-central/com.google.cloud.tools/jib-maven-plugin)
[](https://gitter.im/google/jib)

# Jib - Containerize your Maven project

Jib is a [Maven](https://maven.apache.org/) plugin for building Docker and [OCI](https://github.com/opencontainers/image-spec) images for your Java applications.

For the Gradle plugin, see the [jib-gradle-plugin project](../jib-gradle-plugin).

For information about the project, see the [Jib project README](../README.md).

| ☑️  Jib User Survey |
| :----- |
| What do you like best about Jib? What needs to be improved? Please tell us by taking a [one-minute survey](https://forms.gle/YRFeamGj51xmgnx28). Your responses will help us understand Jib usage and allow us to serve our customers (you!) better. |

## Table of Contents

* [Upcoming Features](#upcoming-features)
* [Quickstart](#quickstart)
  * [Setup](#setup)
  * [Configuration](#configuration)
  * [Build your image](#build-your-image)
    * [Build to Docker Daemon](#build-to-docker-daemon)
    * [Build an image tarball](#build-an-image-tarball)
  * [Bind to a lifecycle](#bind-to-a-lifecycle)
  * [Additional Build Artifacts](#additional-build-artifacts)
* [Multi Module Projects](#multi-module-projects)
* [Extended Usage](#extended-usage)
  * [Configuration Properties](#configuration-properties)
  * [Global Jib Configuration](#global-jib-configuration)
  * [Example](#example)
  * [Adding Arbitrary Files to the Image](#adding-arbitrary-files-to-the-image)
  * [Authentication Methods](#authentication-methods)
    * [Using Docker configuration files](#using-docker-configuration-files)
    * [Using Docker Credential Helpers](#using-docker-credential-helpers)
    * [Using Specific Credentials](#using-specific-credentials)
    * [Using Maven Settings](#using-maven-settings)
  * [Custom Container Entrypoint](#custom-container-entrypoint)
  * [Jib Extensions](#jib-extensions)
  * [WAR Projects](#war-projects)
  * [Skaffold Integration](#skaffold-integration)
* [Need Help?](#need-help)
* [Community](#community)

## Quickstart

You can containerize your application easily with one command:

```shell
mvn compile com.google.cloud.tools:jib-maven-plugin:3.5.2:build -Dimage=<MY IMAGE>
```

This builds and pushes a container image for your application to a container registry. *If you encounter authentication issues, see [Authentication Methods](#authentication-methods).*

To build to a Docker daemon, use:

```shell
mvn compile com.google.cloud.tools:jib-maven-plugin:3.5.2:dockerBuild
```

If you would like to set up Jib as part of your Maven build, follow the guide below.

### Setup

In your Maven Java project, add the plugin to your `pom.xml`:

```xml
<project>
  ...
  <build>
    <plugins>
      ...
      <plugin>
        <groupId>com.google.cloud.tools</groupId>
        <artifactId>jib-maven-plugin</artifactId>
        <version>3.5.2</version>
        <configuration>
          <to>
            <image>myimage</image>
          </to>
        </configuration>
      </plugin>
      ...
    </plugins>
  </build>
  ...
</project>
```

### Configuration

Configure the plugin by setting the image to push to:

#### Using [Google Container Registry (GCR)](https://cloud.google.com/container-registry/)...

*Make sure you have the [`docker-credential-gcr` command line tool](https://cloud.google.com/container-registry/docs/advanced-authentication#docker_credential_helper). Jib automatically uses `docker-credential-gcr` for obtaining credentials. See [Authentication Methods](#authentication-methods) for other ways of authenticating.*

For example, to build the image `gcr.io/my-gcp-project/my-app`, the configuration would be:

```xml
<configuration>
  <to>
    <image>gcr.io/my-gcp-project/my-app</image>
  </to>
</configuration>
```

#### Using [Amazon Elastic Container Registry (ECR)](https://aws.amazon.com/ecr/)...

*Make sure you have the [`docker-credential-ecr-login` command line tool](https://github.com/awslabs/amazon-ecr-credential-helper). Jib automatically uses `docker-credential-ecr-login` for obtaining credentials. See [Authentication Methods](#authentication-methods) for other ways of authenticating.*

For example, to build the image `aws_account_id.dkr.ecr.region.amazonaws.com/my-app`, the configuration would be:

```xml
<configuration>
  <to>
    <image>aws_account_id.dkr.ecr.region.amazonaws.com/my-app</image>
  </to>
</configuration>
```

#### Using [Docker Hub Registry](https://hub.docker.com/)...

*Make sure you have a [docker-credential-helper](https://github.com/docker/docker-credential-helpers#available-programs) set up. For example, on macOS, the credential helper would be `docker-credential-osxkeychain`. See [Authentication Methods](#authentication-methods) for other ways of authenticating.*

For example, to build the image `my-docker-id/my-app`, the configuration would be:

```xml
<configuration>
  <to>
    <image>docker.io/my-docker-id/my-app</image>
  </to>
</configuration>
```

#### Using [JFrog Container Registry (JCR)](https://jfrog.com/container-registry) or [JFrog Artifactory](https://jfrog.com/help/r/jfrog-artifactory-documentation/getting-started-with-artifactory-as-a-docker-registry)...

*Make sure you have a [docker-credential-helper](https://github.com/docker/docker-credential-helpers#available-programs) set up. For example, on macOS, the credential helper would be `docker-credential-osxkeychain`. See [Authentication Methods](#authentication-methods) for other ways of authenticating.*

For example, to build the image `my-company-docker-local.jfrog.io/my-app`, the configuration would be:

```xml
<configuration>
  <to>
    <image>my-company-docker-local.jfrog.io/my-app</image>
  </to>
</configuration>
```

#### Using [Azure Container Registry (ACR)](https://azure.microsoft.com/en-us/services/container-registry/)...

*Make sure you have a [`ACR Docker Credential Helper`](https://github.com/Azure/acr-docker-credential-helper) installed and set up. For example, on Windows, the credential helper would be `docker-credential-acr-windows`. See [Authentication Methods](#authentication-methods) for other ways of authenticating.*

For example, to build the image `my_acr_name.azurecr.io/my-app`, the configuration would be:

```xml
<configuration>
  <to>
    <image>my_acr_name.azurecr.io/my-app</image>
  </to>
</configuration>
```

### Build your image

Build your container image with:

```shell
mvn compile jib:build
```

Subsequent builds are much faster than the initial build.

*Having trouble? Let us know by [submitting an issue](/../../issues/new), contacting us on [Gitter](https://gitter.im/google/jib), or posting to the [Jib users forum](https://groups.google.com/forum/#!forum/jib-users).*

#### Build to Docker daemon

Jib can also build your image directly to a Docker daemon. This uses the `docker` command line tool and requires that you have `docker` available on your `PATH`.

```shell
mvn compile jib:dockerBuild
```

If you are using [`minikube`](https://github.com/kubernetes/minikube)'s remote Docker daemon, make sure you [set up the correct environment variables](https://minikube.sigs.k8s.io/docs/handbook/pushing/#1-pushing-directly-to-the-in-cluster-docker-daemon-docker-env) to point to the remote daemon:

```shell
eval $(minikube docker-env)
mvn compile jib:dockerBuild
```

Alternatively, you can set environment variables in the Jib configuration. See [`dockerClient`](#dockerclient-object) for more configuration options.

#### Build an image tarball

You can build and save your image to disk as a tarball with:

```shell
mvn compile jib:buildTar
```

This builds and saves your image to `target/jib-image.tar`, which you can load into docker with:

```shell
docker load --input target/jib-image.tar
```

### Bind to a lifecycle

You can also bind `jib:build` to a Maven lifecycle, such as `package`, by adding the following execution to your `jib-maven-plugin` definition:

```xml
<plugin>
  <groupId>com.google.cloud.tools</groupId>
  <artifactId>jib-maven-plugin</artifactId>
  ...
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>build</goal>
      </goals>
    </execution>
  </executions>
</plugin>
```

Then, you can build your container image by running:

```shell
mvn package
```

### Additional Build Artifacts

As part of an image build, Jib also writes out the _image digest_ and the _image ID_. By default, these are written out to `target/jib-image.digest` and `target/jib-image.id` respectively, but the locations can be configured using the `<outputPaths><digest>` and `<outputPaths><imageId>` configuration properties. See [Extended Usage](#outputpaths-object) for more details.

## Multi Module Projects

Special handling of project dependencies is recommended when building complex
multi module projects. See [Multi Module Example](https://github.com/GoogleContainerTools/jib/tree/master/examples/multi-module) for detailed information.

## Extended Usage

Extended configuration options provide additional options for customizing the image build.

Field | Type | Default | Description
--- | --- | --- | ---
`to` | [`to`](#to-object) | *Required* | Configures the target image to build your application to.
`from` | [`from`](#from-object) | See [`from`](#from-object) | Configures the base image to build your application on top of.
`container` | [`container`](#container-object) | See [`container`](#container-object) | Configures the container that is run from your image.
`extraDirectories` | [`extraDirectories`](#extradirectories-object) | See [`extraDirectories`](#extradirectories-object) | Configures the directories used to add arbitrary files to the image.
`outputPaths` | [`outputPaths`](#outputpaths-object) | See [`outputPaths`](#outputpaths-object) | Configures the locations of additional build artifacts generated by Jib.
`dockerClient` | [`dockerClient`](#dockerclient-object) | See [`dockerClient`](#dockerclient-object) | Configures Docker for building to/from the Docker daemon.
`skaffold` | [`skaffold`](#skaffold-integration) | See [`skaffold`](#skaffold-integration) | Configures the internal skaffold goals. This configuration should only be used when integrating with [`skaffold`](#skaffold-integration). |
`containerizingMode` | string | `exploded` | If set to `packaged`, puts the JAR artifact built at `${project.build.directory}/${project.build.finalName}.jar` (the default location where many JAR-building plugins put a JAR registered as a main artifact, such as the Maven JAR Plugin) into the final image. If set to `exploded` (default), containerizes individual `.class` files and resources files.
`allowInsecureRegistries` | boolean | `false` | If set to true, Jib ignores HTTPS certificate errors and may fall back to HTTP as a last resort. Leaving this parameter set to `false` is strongly recommended, since HTTP communication is unencrypted and visible to others on the network, and insecure HTTPS is no better than plain HTTP. [If accessing a registry with a self-signed certificate, adding the certificate to your Java runtime's trusted keys](https://github.com/GoogleContainerTools/jib/tree/master/docs/self_sign_cert.md) may be an alternative to enabling this option.
`skip` | boolean | `false` | If set to true, Jib execution is skipped (useful for multi-module projects). This can also be specified via the `-Djib.skip` command line option.

<a name="from-object"></a>`from` is an object with the following properties:

Property | Type | Default                                                   | Description
--- | --- |-----------------------------------------------------------| ---
`image` | string | `eclipse-temurin:{8,11,17,21,25}-jre` (or `jetty` for WAR) | The image reference for the base image. The source type can be specified using a [special type prefix](#setting-the-base-image).
`auth` | [`auth`](#auth-object) | *None*                                                    | Specifies credentials directly (alternative to `credHelper`).
`credHelper` | string | *None*                                                    | Specifies a credential helper that can authenticate pulling the base image. This parameter can either be configured as an absolute path to the credential helper executable or as a credential helper suffix (following `docker-credential-`).
`platforms` | list | See [`platform`](#platform-object)                        | Configures platforms of base images to select from a manifest list.

<a name="to-object"></a>`to` is an object with the following properties:

Property | Type | Default | Description
--- | --- | --- | ---
`image` | string | *Required* | The image reference for the target image. This can also be specified via the `-Dimage` command line option. If the tag is not present here `:latest` is implied.
`auth` | [`auth`](#auth-object) | *None* | Specifies credentials directly (alternative to `credHelper`).
`credHelper` | string | *None* | Specifies a credential helper that can authenticate pushing the target image. This parameter can either be configured as an absolute path to the credential helper executable or as a credential helper suffix (following `docker-credential-`).
`tags` | list | *None* | Additional tags to push to.

<a name="auth-object"></a>`auth` is an object with the following properties (see [Using Specific Credentials](#using-specific-credentials)):

Property | Type
--- | ---
`username` | string
`password` | string

<a name="platform-object"></a>`platform` is an object with the following properties:

Property | Type | Default | Description
--- | --- | --- | ---
`architecture` | string | `amd64` | The architecture of a base image to select from a manifest list.
`os` | string | `linux` | The OS of a base image to select from a manifest list.

See [How do I specify a platform in the manifest list (or OCI index) of a base image?](../docs/faq.md#how-do-i-specify-a-platform-in-the-manifest-list-or-oci-index-of-a-base-image) for examples.

<a name="container-object"></a>`container` is an object with the following properties:

Property | Type | Default | Description
--- | --- | --- | ---
`appRoot` | string | `/app` | The root directory on the container where the app's contents are placed. Particularly useful for WAR-packaging projects to work with different Servlet engine base images by designating where to put exploded WAR contents; see [WAR usage](#war-projects) as an example.
`args` | list | *None* | Additional program arguments appended to the command to start the container (similar to Docker's [CMD](https://docs.docker.com/engine/reference/builder/#cmd) instruction in relation with [ENTRYPOINT](https://docs.docker.com/engine/reference/builder/#entrypoint)). In the default case where you do not set a custom `entrypoint`, this parameter is effectively the arguments to the main method of your Java application.
`creationTime` | string | `EPOCH` | Sets the container creation time. (Note that this property does not affect the file modification times, which are configured using `<filesModificationTime>`.) The value can be `EPOCH` to set the timestamps to Epoch (default behavior), `USE_CURRENT_TIMESTAMP` to forgo reproducibility and use the real creation time, or an ISO 8601 date-time parsable with [`DateTimeFormatter.ISO_DATE_TIME`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/DateTimeFormatter.html#ISO_DATE_TIME) such as `2019-07-15T10:15:30+09:00` or `2011-12-03T22:42:05Z`.
`entrypoint` | list | *None* | The command to start the container with (similar to Docker's [ENTRYPOINT](https://docs.docker.com/engine/reference/builder/#entrypoint) instruction). If set, then `jvmFlags`, `mainClass`, `extraClasspath`, and `expandClasspathDependencies` are ignored. You may also set `<entrypoint>INHERIT</entrypoint>` (`<entrypoint><entry>INHERIT</entry></entrypoint>` in old Maven versions) to indicate that the `entrypoint` and `args` should be inherited from the base image.\*
`environment` | map | *None* | Key-value pairs for setting environment variables on the container (similar to Docker's [ENV](https://docs.docker.com/engine/reference/builder/#env) instruction).
`extraClasspath` | list | *None* | Additional paths in the container to prepend to the computed Java classpath.
`expandClasspathDependencies` | boolean | `false` | <ul><li>Java 8 *or* Jib < 3.1: When set to true, does not use a wildcard (for example, `/app/lib/*`) for dependency JARs in the default Java runtime classpath but instead enumerates the JARs. Has the effect of preserving the classpath loading order as defined by the Maven project.</li><li>Java >= 9 *and* Jib >= 3.1: The option has no effect. Jib *always* enumerates the dependency JARs. This is achieved by [creating and using an argument file](#custom-container-entrypoint) for the `--class-path` JVM argument.</li></ul>
`filesModificationTime` | string | `EPOCH_PLUS_SECOND` | Sets the modification time (last modified time) of files in the image put by Jib. (Note that this does not set the image creation time, which can be set using `<creationTime>`.) The value should either be `EPOCH_PLUS_SECOND` to set the timestamps to Epoch + 1 second (default behavior), or an ISO 8601 date-time parsable with [`DateTimeFormatter.ISO_DATE_TIME`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/DateTimeFormatter.html#ISO_DATE_TIME) such as `2019-07-15T10:15:30+09:00` or `2011-12-03T22:42:05Z`.
`format` | string | `Docker` | Use `OCI` to build an [OCI container image](https://www.opencontainers.org/).
`jvmFlags` | list | *None* | Additional flags to pass into the JVM when running your application.
`labels` | map | *None* | Key-value pairs for applying image metadata (similar to Docker's [LABEL](https://docs.docker.com/engine/reference/builder/#label) instruction).
`mainClass` | string | *Inferred*\*\* | The main class to launch the application from.
`ports` | list | *None* | Ports that the container exposes at runtime (similar to Docker's [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose) instruction).
`user` | string | *None* | The user and group to run the container as. The value can be a username or UID along with an optional groupname or GID. The following are all valid: `user`, `uid`, `user:group`, `uid:gid`, `uid:group`, `user:gid`.
`volumes` | list | *None* | Specifies a list of mount points on the container.
`workingDirectory` | string | *None* | The working directory in the container.

<a name="extradirectories-object"></a>`extraDirectories` is an object with the following properties (see [Adding Arbitrary Files to the Image](#adding-arbitrary-files-to-the-image)):

Property | Type | Default | Description
--- | --- | --- | ---
`paths` | list | `[(project-dir)/src/main/jib]` | List of [`path`](#path-object) objects and/or extra directory paths. Can be absolute or relative to the project root.
`permissions` | list | *None* | Maps file paths (glob patterns) on container to Unix permissions. (Effective only for files added from extra directories.) If not configured, permissions default to "755" for directories and "644" for files. See [Adding Arbitrary Files to the Image](#adding-arbitrary-files-to-the-image) for an example.

<a name="path-object"></a>`path` is an object with the following properties (see [Adding Arbitrary Files to the Image](#adding-arbitrary-files-to-the-image)):

Property | Type | Default | Description
--- | --- | --- | ---
`from` | file | `[(project-dir)/src/main/jib]` | The source directory. Can be absolute or relative to the project root.
`into` | string | `/` | The absolute unix path on the container to copy the extra directory contents into.
`includes` | list | *None* | Glob patterns for including files. See [Adding Arbitrary Files to the Image](#adding-arbitrary-files-to-the-image) for an example.
`excludes` | list | *None* | Glob patterns for excluding files. See [Adding Arbitrary Files to the Image](#adding-arbitrary-files-to-the-image) for an example.

<a name="outputpaths-object"></a>`outputPaths` is an object with the following properties:

Property | Type | Default | Description
--- | --- | --- | ---
`tar` | string | `(project-dir)/target/jib-image.tar` | The path of the tarball generated by `jib:buildTar`. Relative paths are resolved relative to the project root.
`digest` | string | `(project-dir)/target/jib-image.digest` | The path of the image digest written out during the build. Relative paths are resolved relative to the project root.
`imageId` | string | `(project-dir)/target/jib-image.id` | The path of the image ID written out during the build. Relative paths are resolved relative to the project root.
`imageJson` | string | `(project-dir)/target/jib-image.json` | The path of the image metadata json file written out during the build. Relative paths are resolved relative to the project root.

<a name="dockerclient-object"></a>`dockerClient` is an object used to configure Docker when building to/from the Docker daemon. It has the following properties:

Property | Type | Default | Description
--- | --- | --- | ---
`executable` | string | `docker` | Sets the path to the Docker executable that is called to load the image into the Docker daemon. **Please note**: Users are responsible for ensuring that the Docker path passed in is valid and has the right permissions to be executed.
`environment` | map | *None* | Sets environment variables used by the Docker executable.

#### Configuration Properties

Each of these parameters is configurable via commandline using properties. Jib's properties follow the same naming convention as the configuration parameters, with each level separated by dots (i.e. `-Djib.parameterName[.nestedParameter.[...]]=value`). Some examples are below:
```shell
mvn compile jib:build \
    -Djib.to.image=myregistry/myimage:latest \
    -Djib.to.auth.username=$USERNAME \
    -Djib.to.auth.password=$PASSWORD

mvn compile jib:dockerBuild \
    -Djib.dockerClient.executable=/path/to/docker \
    -Djib.container.environment=key1="value1",key2="value2" \
    -Djib.container.args=arg1,arg2,arg3
```

The following table contains additional properties that are not available as build configuration parameters:

Property | Type | Default | Description
--- | --- | --- | ---
`jib.httpTimeout` | int | `20000` | HTTP connection/read timeout for registry interactions, in milliseconds. Use a value of `0` for an infinite timeout.
`jib.useOnlyProjectCache` | boolean | `false` | If set to true, Jib does not share a cache between different Maven projects (i.e. `jib.baseImageCache` defaults to `[project dir]/target/jib-cache` instead of `[user cache home]/google-cloud-tools-java/jib`).
`jib.baseImageCache` | string | *Platform-dependent*\*\*\* | Sets the directory to use for caching base image layers. This cache can (and should) be shared between multiple images.
`jib.applicationCache` | string | `[project dir]/target/jib-cache` | Sets the directory to use for caching application layers. This cache can be shared between multiple images.
`jib.console` | string | *None* | If set to `plain`, Jib will print plaintext log messages rather than display a progress bar during the build.

*\* If you configure `args` while `entrypoint` is set to `'INHERIT'`, the configured `args` value will take precedence over the CMD propagated from the base image.*

*\*\* Uses the main class defined in the `jar` task or tries to find a valid main class.*

*\*\*\* The default base image cache is in the following locations on each platform:*
 * *Linux: `[cache root]/google-cloud-tools-java/jib/`, where `[cache root]` is `$XDG_CACHE_HOME` (`$HOME/.cache/` if not set)*
 * *Mac: `[cache root]/Google/Jib/`, where `[cache root]` is `$XDG_CACHE_HOME` (`$HOME/Library/Caches/` if not set)*
 * *Windows: `[cache root]\Google\Jib\Cache`, where `[cache root]` is `%XDG_CACHE_HOME%` (`%LOCALAPPDATA%` if not set)*

### Global Jib Configuration

Some options can be set in the global Jib configuration file. The file is at the following locations on each platform:

* *Linux: `[config root]/google-cloud-tools-java/jib/config.json`, where `[config root]` is `$XDG_CONFIG_HOME` (`$HOME/.config/` if not set)*
* *Mac: `[config root]/Google/Jib/config.json`, where `[config root]` is `$XDG_CONFIG_HOME` (`$HOME/Library/Preferences/` if not set)*
* *Windows: `[config root]\Google\Jib\Config\config.json`, where `[config root]` is `%XDG_CONFIG_HOME%` (`%LOCALAPPDATA%` if not set)*

#### Properties

* `disableUpdateCheck`: when set to true, disables the periodic up-to-date version check.
* `registryMirrors`: a list of mirror settings for each base image registry. In the following example, if the base image configured in Jib is for a Docker Hub image, then `mirror.gcr.io`, `localhost:5000`, and the Docker Hub (`registry-1.docker.io`) are tried in order until Jib can successfully pull a base image.

```json
{
  "disableUpdateCheck": false,
  "registryMirrors": [
    {
      "registry": "registry-1.docker.io",
      "mirrors": ["mirror.gcr.io", "localhost:5000"]
    },
    {
      "registry": "quay.io",
      "mirrors": ["private-mirror.test.com"]
    }
  ]
}
```
**Note about `mirror.gcr.io`**: it is _not_ a Docker Hub mirror but a cache. It caches [frequently-accessed public Docker Hub images](https://cloud.google.com/container-registry/docs/pulling-cached-images), and it's often possible that your base image does not exist in `mirror.gcr.io`. In that case, Jib will have to fall back to use Docker Hub.

### Example

In this configuration, the image:
* Is built from a base of `openjdk:alpine` (pulled from Docker Hub)
* Is pushed to `localhost:5000/my-image:built-with-jib`, `localhost:5000/my-image:tag2`, and `localhost:5000/my-image:latest`
* Runs by calling `java -Dmy.property=example.value -Xms512m -Xdebug -cp app/libs/*:app/resources:app/classes mypackage.MyApp some args`
* Exposes port 1000 for tcp (default), and ports 2000, 2001, 2002, and 2003 for udp
* Has two labels (key1:value1 and key2:value2)
* Is built as OCI format

```xml
<configuration>
  <from>
    <image>openjdk:alpine</image>
  </from>
  <to>
    <image>localhost:5000/my-image:built-with-jib</image>
    <credHelper>osxkeychain</credHelper>
    <tags>
      <tag>tag2</tag>
      <tag>latest</tag>
    </tags>
  </to>
  <container>
    <jvmFlags>
      <jvmFlag>-Dmy.property=example.value</jvmFlag>
      <jvmFlag>-Xms512m</jvmFlag>
      <jvmFlag>-Xdebug</jvmFlag>
    </jvmFlags>
    <mainClass>mypackage.MyApp</mainClass>
    <args>
      <arg>some</arg>
      <arg>args</arg>
    </args>
    <ports>
      <port>1000</port>
      <port>2000-2003/udp</port>
    </ports>
    <labels>
      <key1>value1</key1>
      <key2>value2</key2>
    </labels>
    <format>OCI</format>
  </container>
</configuration>
```

### Setting the Base Image

There are three different types of base images that Jib accepts: an image from a container registry, an image stored in the Docker daemon, or an image tarball on the local filesystem. You can specify which you would like to use by prepending the `<from><image>` configuration with a special prefix, listed below:

Prefix | Example | Type
--- | --- | ---
*None* | `openjdk:11-jre` | Pulls the base image from a registry.
`registry://` | `registry://eclipse-temurin:11-jre` | Pulls the base image from a registry.
`docker://` | `docker://busybox` | Retrieves the base image from the Docker daemon.
`tar://` | `tar:///path/to/file.tar` | Uses an image tarball stored at the specified path as the base image. Also accepts relative paths (e.g. `tar://target/jib-image.tar`).

### Adding Arbitrary Files to the Image

You can add arbitrary, non-classpath files to the image by placing them in a `src/main/jib` directory. This will copy all files within the `jib` folder to the target directory (`/` by default) in the image, maintaining the same structure (e.g. if you have a text file at `src/main/jib/dir/hello.txt`, then your image will contain `/dir/hello.txt` after being built with Jib).

Note that Jib does not follow symbolic links in the container image.  If a symbolic link is present, _it will be removed_ prior to placing the files and directories.

You can configure different directories by using the `<extraDirectories>` parameter in your `pom.xml`:
```xml
<configuration>
  
  <extraDirectories>
    <paths>
      
      <path>src/main/custom-extra-dir</path>
      
      <path>
        <from>/home/user/jib-extras</from>
        <into>/extras</into>
      </path>
    </paths>
  </extraDirectories>
</configuration>
```

Alternatively, the `<extraDirectories>` parameter can be used as an object to set custom extra directories, as well as the extra files' permissions on the container:

```xml
  <extraDirectories>
    <paths>src/main/custom-extra-dir</paths> 
    <permissions>
      <permission>
        <file>/path/on/container/to/fileA</file>
        <mode>755</mode> 
      </permission>
      <permission>
        <file>/path/to/another/file</file>
        <mode>644</mode> 
      </permission>
      <permission>
        <file>/glob/pattern/**/*.sh</file>
        <mode>755</mode>
      </permission>
    </permissions>
  </extraDirectories>
```

You may also specify the target of the copy and include or exclude files:

```xml
  <extraDirectories>
    <paths>
      <path>
        // copies the contents of 'src/main/extra-dir' into '/' on the container
        <from>src/main/extra-dir</from>
      </path>
      <path>
        // copies the contents of 'src/main/another/dir' into '/extras' on the container
        <from>src/main/another/dir</from>
        <into>/extras</into>
      </path>
      <path>
        // copies a single-file.xml
        <from>src/main/resources/xml-files</from>
        <into>/dest-in-container</into>
        <includes>single-file.xml</includes>
      </path>
      <path>
        // copies only .txt files except for 'hidden.txt' at the source root
        <from>build/some-output</from>
        <into>/txt-files</into>
        <includes>*.txt,**/*.txt</includes>
        <excludes>
          <exclude>hidden.txt</exclude>
        </excludes>
      </path>
    </paths>
  </extraDirectories>
```

### Authentication Methods

Pushing/pulling from private registries require authorization credentials.

#### Using Docker configuration files

* Jib looks from credentials from `$XDG_RUNTIME_DIR/containers/auth.json`, `$XDG_CONFIG_HOME/containers/auth.json`, `$HOME/.config/containers/auth.json`, `$DOCKER_CONFIG/config.json`, and `$HOME/.docker/config.json`.

See [this issue](/../../issues/101) and [`man containers-auth.json`](https://www.mankier.com/5/containers-auth.json) for more information about the files.

#### Using Docker Credential Helpers

Docker credential helpers are CLI tools that handle authentication with various registries.

Some common credential helpers include:

* Google Container Registry: [`docker-credential-gcr`](https://cloud.google.com/container-registry/docs/advanced-authentication#docker_credential_helper)
* AWS Elastic Container Registry: [`docker-credential-ecr-login`](https://github.com/awslabs/amazon-ecr-credential-helper)
* Docker Hub Registry: [`docker-credential-*`](https://github.com/docker/docker-credential-helpers)
* Azure Container Registry: [`docker-credential-acr-*`](https://github.com/Azure/acr-docker-credential-helper)

Configure credential helpers to use by specifying them as a `credHelper` for their respective image.

*Example configuration:*
```xml
<configuration>
  ...
  <from>
    <image>aws_account_id.dkr.ecr.region.amazonaws.com/my-base-image</image>
    <credHelper>ecr-login</credHelper>
  </from>
  <to>
    <image>gcr.io/my-gcp-project/my-app</image>
    <credHelper>gcr</credHelper>
  </to>
  ...
</configuration>
```

#### Using Specific Credentials

You can specify credentials directly in the `<auth>` parameter for the `from` and/or `to` images. In the example below, `to` credentials are retrieved from the `REGISTRY_USERNAME` and `REGISTRY_PASSWORD` environment variables.

```xml
<configuration>
  ...
  <from>
    <image>aws_account_id.dkr.ecr.region.amazonaws.com/my-base-image</image>
    <auth>
      <username>my_username</username>
      <password>my_password</password>
    </auth>
  </from>
  <to>
    <image>gcr.io/my-gcp-project/my-app</image>
    <auth>
      <username>${env.REGISTRY_USERNAME}</username>
      <password>${env.REGISTRY_PASSWORD}</password>
    </auth>
  </to>
  ...
</configuration>
```

Alternatively, you can specify credentials via commandline using the following system properties.

Property | Description
--- | ---
`-Djib.from.auth.username` | Username for base image registry.
`-Djib.from.auth.password` | Password for base image registry.
`-Djib.to.auth.username` | Username for target image registry.
`-Djib.to.auth.password` | Password for target image registry.

e.g. `mvn compile jib:build -Djib.to.auth.username=user -Djib.to.auth.password=pass`

**Note:** This method of authentication should be used only as a last resort, as it is insecure to make your password visible in plain text. Note that often cloud registries (for example, Google GCR, Amazon ECR, and Azure ACR) do not accept "user credentials" (such as Gmail account name and password) but require different forms of credentials. For example, you may use [`oauth2accesstoken` or `_json_key`](https://cloud.google.com/container-registry/docs/advanced-authentication) as the username for GCR, and [`AWS`](https://serverfault.com/questions/1004915/what-is-the-proper-way-to-log-in-to-ecr) for ECR. For ACR, you may use a [_service principle_](https://docs.microsoft.com/en-us/azure/container-registry/container-registry-auth-service-principal).

#### Using Maven Settings

Registry credentials can be added to your [Maven settings](https://maven.apache.org/settings.html). These credentials will be used if credentials could not be found in any specified Docker credential helpers.

If you're considering putting credentials in Maven, we highly *recommend* using [maven password encryption](https://maven.apache.org/guides/mini/guide-encryption.html).

*Example `settings.xml`:*
```xml
<settings>
  ...
  <servers>
    ...
    <server>
      <id>MY_REGISTRY</id>
      <username>MY_USERNAME</username>
      <password>{MY_SECRET}</password>
    </server>
  </servers>
</settings>
```

* The `id` field should be the registry server these credentials are for.
* We *do not* recommend putting your raw password in `settings.xml`.


### Custom Container Entrypoint

If you don't set `<container><entrypoint>`, the default container entrypoint to launch your app will be basically `java -cp <runtime classpath> <app main class>`. (The final `java` command can be further configured by setting `<container>{<jvmFlags>|<args>|<extraClasspath>|<mainClass>|<expandClasspathDependencies>}`.)

Sometimes, you'll want to set a custom entrypoint to use a shell to wrap the `java` command. For example, to let `sh` or `bash` [expand environment variables](https://stackoverflow.com/a/59361658/1701388), or to have more sophisticated logic to construct a launch command. (Note, however, that running a command with a shell forks a new child process unless you run it with `exec` like `sh -c "exec java ..."`. Whether to run the JVM process as PID 1 or a child process of a PID-1 shell is a [decision you should make carefully](https://github.com/GoogleContainerTools/distroless/issues/550#issuecomment-791610603).) In this scenario, you will want to have a way inside a shell script to reliably know the default runtime classpath and the main class that Jib would use by default. To help this, Jib >= 3.1 creates two JVM argument files under `/app` (the default app root) inside the built image.

- `/app/jib-classpath-file`: runtime classpath that Jib would use for default app launch
- `/app/jib-main-class-file`: main class

Therefore, *for example*, the following commands will be able to launch your app:

- (Java 9+) `java -cp @/app/jib-classpath-file @/app/jib-main-class-file`
- (with shell) `java -cp $( cat /app/jib-classpath-file ) $( cat /app/jib-main-class-file )`


### Jib Extensions

The Jib build plugins have an extension framework that enables anyone to easily extend Jib's behavior to their needs. We maintain select [first-party](https://github.com/GoogleContainerTools/jib-extensions/tree/master/first-party) plugins for popular use cases like [fine-grained layer control](https://github.com/GoogleContainerTools/jib-extensions/tree/master/first-party/jib-layer-filter-extension-gradle), builds a [GraalVM native image](https://github.com/GoogleContainerTools/jib-extensions/tree/master/first-party/jib-native-image-extension-maven), and [Quarkus support](https://github.com/GoogleContainerTools/jib-extensions/tree/master/first-party/jib-quarkus-extension-gradle), but anyone can write and publish an extension. Check out the [jib-extensions](https://github.com/GoogleContainerTools/jib-extensions) repository for more information.


### WAR Projects

Jib also containerizes WAR projects. If the Maven project uses [the `war`-packaging type](https://maven.apache.org/plugins/maven-war-plugin/index.html), Jib will by default use [`jetty`](https://hub.docker.com/_/jetty) as a base image to deploy the project WAR. No extra configuration is necessary other than having the packaging type to `war`.

Note that Jib will work slightly differently for WAR projects from JAR projects:
   - `<container><mainClass>` and `<container><jvmFlags>` are ignored.
   - The WAR will be exploded into `/var/lib/jetty/webapps/ROOT`, which is the expected WAR location for the Jetty base image.

To use a different Servlet engine base image, you can customize `<container><appRoot>`, `<container><entrypoint>`, and `<container><args>`. If you do not set `entrypoint` or `args`, Jib will inherit the `ENTRYPOINT` and `CMD` of the base image, so in many cases, you may not need to configure them. However, you will most likely have to set `<container><appRoot>` to a proper location depending on the base image. Here is an example of using a Tomcat image:

```xml
<configuration>
  <from>
    <image>tomcat:8.5-jre8-alpine</image>
  </from>
  <container>
    
    <appRoot>/usr/local/tomcat/webapps/ROOT</appRoot>
  </container>
</configuration>
```
When specifying a [`jetty`](https://hub.docker.com/_/jetty) image yourself with `<from><image>`, you may run into an issue ([#3204](https://github.com/GoogleContainerTools/jib/issues/3204)) and need to override the entrypoint.
```xml
<configuration>
  <from>
    <image>jetty:11.0.2-jre11</image>
  </from>
  <container>
    <entrypoint>java,-jar,/usr/local/jetty/start.jar</entrypoint>
  </container>
</configuration>
```


### Skaffold Integration

Jib is an included builder in [Skaffold](https://github.com/GoogleContainerTools/skaffold). Jib passes build information to skaffold through special internal goals so that skaffold understands when it should rebuild or synchronize files. For complex builds, the defaults may not be sufficient, so the jib plugin provides a `skaffold` configuration object which exposes:

Field | Type | Default | Description
--- | --- | --- | ---
`watch` | [`watch`](#skaffold-watch-object) | *None* | Additional configuration for file watching
`sync` | [`sync`](#skaffold-sync-object) | *None* | Additional configuration for file synchronization

<a name="skaffold-watch-object"></a>`watch` is an object with the following properties:

Field | Type | Default | Description
--- | --- | --- | ---
`buildIncludes` | `List<String>` | *None* | Additional build files that skaffold should watch
`includes` | `List<String>` | *None* | Additional project files or directories that skaffold should watch
`excludes` | `List<String>` | *None* | Files and directories that skaffold should not watch

<a name="skaffold-sync-object"></a>`sync` is an object with the following properties:

Field | Type | Default | Description
--- | --- | --- | ---
`excludes` | `List<String>` | *None* | Files and directories that skaffold should not sync

## <a name=frequently-asked-questions-faq></a>Need Help?

A lot of questions are already answered!

* [Frequently Asked Questions (FAQ)](../docs/faq.md)
* [Stack Overflow](https://stackoverflow.com/questions/tagged/jib)
* [GitHub issues](https://github.com/GoogleContainerTools/jib/issues)

_For usage questions, please ask them on Stack Overflow._

## Privacy

See the [Privacy page](docs/privacy.md).

## Upcoming Features

See [Milestones](https://github.com/GoogleContainerTools/jib/milestones) for planned features. [Get involved with the community](https://github.com/GoogleContainerTools/jib/tree/master#get-involved-with-the-community) for the latest updates.

## Community

See the [Jib project README](/../../#community).

## Disclaimer

This is not an officially supported Google product.

---

### Overview (`jib-plugins-common/README.md`)

Common code for Jib plugins. NOT intended for use outside of `jib-maven-plugin` or `jib-gradle-plugin` in its current state.

---

### Overview (`proposals/README.md`)

# Design Documents and Proposals

This directory holds the approved design documents and proposals for changes and new features to Jib.

## Contribute

### Submit a Proposal

Submit a proposal by filing a pull request that adds a `<proposal_name>.md` file to this directory.

Follow the general layout of existing proposals. In general, make sure to include:

- Description of the problem
- Goals to achieve
- Proposed solution to the problem

Proposals are approved upon merge.

### Review a Proposal

Review pending proposals by commenting on [their pull requests](/../../pulls?q=is%3Aopen+is%3Apr+label%3Aproposal). Proposals in review are labelled with `proposal`.

For approved proposals, you may open revision pull requests with your suggestions for revision, or provide your comments in a new [issue](/../../issues/new?body=&lt;!--%20Please%20provide%20the%20link%20to%20the%20approved%20proposal%20you%20are%20commenting%20on.%20--&gt;) or messaging the [community](/../../#community).

---

### Overview (`examples/dropwizard/README.md`)

# Containerize a [Dropwizard](https://dropwizard.io) application with Jib

## How to start the Dropwizard application

1. Run `./mvnw clean package` to build your container
1. Start the application
    - **With Docker**: `docker run --rm -p 8080:8080 dropwizard-jib-example:1`
    - **Without Docker**: `./mvnw exec:java`
1. Check that your application is running at http://localhost:8080

## Health Check

See your application's health at http://localhost:8080/admin/healthcheck

## Extras

FreeMaker templating is setup for [`dropwizard.yml`](src/main/resources/dropwizard.yml) through [`tkrille/dropwizard-template-config`](https://github.com/tkrille/dropwizard-template-config); this allows one to heavily customize the properties file via the container environment with FTL conditional checks and for loops, for example.

## How this example was generated

Starter Maven template generated with [`dropwizard-archetypes`](https://github.com/dropwizard/dropwizard/tree/master/dropwizard-archetypes)

```sh
mvn archetype:generate \
  -DarchetypeGroupId=io.dropwizard.archetypes \
  -DarchetypeArtifactId=example \
  -DarchetypeVersion=[REPLACE ME WITH A VALID DROPWIZARD VERSION]
```

Ref. [Dropwizard - Getting Started, Setting up With Maven](https://www.dropwizard.io/1.3.5/docs/getting-started.html#setting-up-using-maven)

The remainder of the archetype code was filled-in following the above guide.

## More information

Learn [more about Jib](https://github.com/GoogleContainerTools/jib).

Learn [more about Dropwizard](https://dropwizard.io).

## Build and run on Google Cloud

[](https://deploy.cloud.run?git_repo=https://github.com/GoogleContainerTools/jib.git&dir=examples/dropwizard)

---

### Overview (`examples/helloworld/README.md`)

Builds a container image that outputs `Hello World` when run.

To build the image:

1. In `pom.xml` or `build.gradle`, replace `REPLACE-WITH-YOUR-GCP-PROJECT` with your GCP project.

1. Run `mvn compile jib:build` or `./gradlew jib`.

---

### Overview (`examples/java-agent/README.md`)

This SparkJava-based example builds a container image that includes the [Stackdriver Debugger Java Agent](https://cloud.google.com/debugger/docs/).
This project assumes the resulting image will be run inside Google Cloud Platform.

To build the image:

1. Replace `REPLACE-WITH-YOUR-GCP-PROJECT` with your GCP project in `pom.xml` or `build.gradle`.

1. Run `mvn package` or `./gradlew` to build the image.

SparkJava listens on port 4567 by default.

## Build and run on Google Cloud

[](https://deploy.cloud.run?git_repo=https://github.com/GoogleContainerTools/jib.git&dir=examples/java-agent)

---

### Overview (`examples/ktor/README.md`)

# Containerize a [Ktor] application with Jib

This is an example of how to easily build a Docker image for a [Ktor] application with Jib.

```shell
./gradlew jibDockerBuild

docker run --rm -p 8080:8080 ktor-jib-example:1
```

The application can also be ran outside of Jib's build process via `./gradlew run`

## Defined environment variables

A few variables have been added in the code-base to show case some of the unique features of Ktor.

- `KTOR_APP_ID` - The name of the application in the logs
    - Type: String
- `KTOR_METRICS_ENABLED` - Exposes JMX Metrics through the application port (`8080`)
    - Type: Boolean (default: `false`)
- `KTOR_ROUTE_TRACING` - Enables verbose logging of route matches for debugging complex/nested routing tables
    - Type: Boolean

## More information

Learn [more about Jib](https://github.com/GoogleContainerTools/jib).

Learn [Ktor].

  [Ktor]: https://ktor.io

---

### Overview (`examples/micronaut/README.md`)

# Containerize a [Micronaut](http://micronaut.io/) app with Jib

This is an example of how to easily build a Docker image for a [Micronaut framework Groovy/Java application](http://guides.micronaut.io/creating-your-first-micronaut-app-groovy/guide/index.html) with Jib.


<p align="center">
    <a href="https://twitter.com/intent/tweet?text=Dockerize%20and%20run%20a%20%22Hello%20World%22%20%40Java%20%40micronautfw%20app%20with%20%23Jib%20in%20seconds&url=https://asciinema.org/a/191805&hashtags=docker,kubernetes">
    <img src="dockerize-micronaut-jib.gif?raw=true" width="600" alt="Dockerize Micronaut app with Jib">
  </a>
</p>

## Quickstart

### With Docker

```shell
./gradlew jibDockerBuild

docker run -d -p 8080:8080 micronaut-jib:0.1
```
```shell
curl localhost:8080/hello
> Hello World
```


Give it a [](https://twitter.com/intent/tweet?text=Dockerize%20and%20run%20a%20%22Hello%20World%22%20%40Java%20%40micronautfw%20app%20with%20%23Jib%20in%20seconds&url=https://github.com/GoogleContainerTools/jib/tree/master/examples/micronaut&hashtags=docker,kubernetes)

### With Kubernetes

```shell
IMAGE=<your image, eg. gcr.io/my-project/micronaut-jib>

./gradlew jib --image=$IMAGE

kubectl run micronaut-jib --image=$IMAGE --port=8080 --restart=Never

# Wait until pod is running
kubectl port-forward micronaut-jib 8080 > /dev/null 2>&1 &
```
```shell
curl localhost:8080/hello
> Hello World
```


Give it a [](https://twitter.com/intent/tweet?text=Run%20a%20%22Hello%20World%22%20%40java%20%40micronautfw%20app%20on%20%23Kubernetes%20with%20%23Jib%20in%20seconds&url=https://github.com/GoogleContainerTools/jib/tree/master/examples/micronaut&hashtags=docker,kubernetes)

## More information

Learn [more about Jib](https://github.com/GoogleContainerTools/jib).
Learn [more about Micronaut](https://micronaut.io).

---

### Overview (`examples/multi-module/README.md`)

# Multi-module example

This example shows how to build multiple containers for a multi-module project in both **Maven** and **Gradle**.

# How the example is set up

The project consists of two microservices and a library:

1. `name-service` - responds with a name
1. `shared-library` - a project dependency used by `name-service`
1. `hello-service` - calls `name-service` and responds with a greeting

The **Maven** project is set up with a parent POM ([`pom.xml`](pom.xml)) that defines most of the common build configuration. The module POMs ([`name-service/pom.xml`](name-service/pom.xml) and [`hello-service/pom.xml`](hello-service/pom.xml)) just define inheritance on the parent POM. However, if needed, the module POMs can define custom configuration on `jib-maven-plugin` specific to that module.

The **Gradle** project is set up with a parent [`build.gradle`](build.gradle) that sets some common configuration up for all projects, with each sub-project containing its own `build.gradle` with some custom configuration. [`settings.gradle`](settings.gradle) defines which modules to include in the overall build.

## Reproducibility of dependency module `shared-library`

Since dependency module builds happen with the underlying build system
(maven/gradle), we must add some extra configuration to ensure that the
resulting `jar` that is built conforms to our reproducibility expectations.
The module [`shared-library`](shared-library) uses the [Reproducible Build Maven Plugin](https://zlika.github.io/reproducible-build-maven-plugin/)
for maven, and some special `Jar` properties ([`preserveFileTimestamps`](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.Jar.html#org.gradle.api.tasks.bundling.Jar:preserveFileTimestamps),
[`reproducibleFileOrder`](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.Jar.html#org.gradle.api.tasks.bundling.Jar:reproducibleFileOrder))
in gradle to achieve this. This configuration can be seen in the
`shared-library`'s [`pom.xml`](shared-library/pom.xml) and [`build.gradle`](shared-library/build.gradle).

Care must be taken when adding custom attributes to a `MANIFEST.MF`.
Attributes whose values change on every build can affect reproducibility even
with the modifications outlined above.

# How to run

Set the `PROJECT_ID` environment variable to your own Google Cloud Platform project:

```shell
export PROJECT_ID=$(gcloud config list --format 'value(core.project)')
```

Run the **Maven** build:

```shell
# build everything
./mvnw package jib:build

# build just hello-service
./mvnw compile jib:build -pl hello-service

# build name-service (with dependency on shared-library)
# you must use "package" for jib to correctly package "shared-library" with the
# "name-service" container
./mvnw package jib:build -pl name-service -am
```

Run the **Gradle** build:

```shell
# build everything
./gradlew jib

# build just hello-service
./gradlew :hello-service:jib

# build name-service (with dependency on shared-library)
./gradlew :name-service:jib
```

You can also run `./maven-build.sh` or `./gradle-build.sh` as a shorthand.

# Where are the containers

The output of the build should have the container image references highlighted in <span style="color: cyan">cyan</span>. You can expect them to be at:

- `name-service`: `gcr.io/PROJECT_ID/name-service:0.1.0`
- `hello-service`: `gcr.io/PROJECT_ID/hello-service:0.1.0`

# How to run on Kubernetes

[`kubernetes.yaml`](kubernetes.yaml) defines the manifests for running the two microservices on Kubernetes. Make sure to open the file and change `PROJECT_ID` to your own Google Cloud Platform project.

Create a Kubernetes cluster:

```shell
gcloud container clusters create jib
```

Apply to your Kubernetes cluster:

```shell
kubectl apply -f kubernetes.yaml
```

Find the `EXTERNAL-IP` of the `hello-service`.

```
NAME                TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
svc/hello-service   LoadBalancer   10.19.243.223   35.237.89.148   80:30196/TCP   1m
```

Visit the IP in your web browser and you should see:

```
Hello Jib Multimodule: A string from 'shared-library'
```

---

### Overview (`examples/spring-boot/README.md`)

# Dockerize a Spring Boot application using Jib

This is an example of how to easily build a Docker image for a Spring Boot application with Jib.

## Try it yourself

You can containerize the application with one of the following commands.

**Maven:**
```shell
./mvnw compile jib:build -Dimage=<your image, eg. gcr.io/my-project/spring-boot-jib>
```

**Gradle:**
```shell
./gradlew jib --image=<your image, eg. gcr.io/my-project/spring-boot-jib>
```

## Deploying to Kubernetes using `kubectl`


<p align="center">
    <a href="https://twitter.com/intent/tweet?text=Dockerize+and+deploy+a+%40springboot+app+to+%23Kubernetes+in+seconds+%40kubernetesio+%40docker+%23jib&url=https://asciinema.org/a/192977">
    <img src="dockerize-spring-boot-jib.gif" width="600" alt="Dockerize Spring Boot app with Jib and deploy to Kubernetes">
  </a>
</p>

*Make sure you have `kubectl` installed and [configured with a cluster](https://cloud.google.com/kubernetes-engine/docs/how-to/creating-a-cluster).*

```shell
IMAGE=<your image, eg. gcr.io/my-project/spring-boot-jib>

./mvnw compile jib:build -Dimage=$IMAGE

kubectl run spring-boot-jib --image=$IMAGE --port=8080 --restart=Never

# Wait until pod is running
kubectl port-forward spring-boot-jib 8080
```
```shell
curl localhost:8080
> Greetings from Spring Boot and Jib!
```

\* If you are using Gradle, use `./gradlew jib --image=$IMAGE` instead of the `./mvnw` command


Give it a [](https://twitter.com/intent/tweet?text=Run+a+%40springboot+app+on+%23Kubernetes+in+seconds+%40kubernetesio+%23jib+%23java&url=https://github.com/GoogleContainerTools/jib/tree/master/examples/spring-boot&hashtags=docker)

## More information

Learn [more about Jib](https://github.com/GoogleContainerTools/jib).

## Build and run on Google Cloud

[](https://deploy.cloud.run?git_repo=https://github.com/GoogleContainerTools/jib.git&dir=examples/spring-boot)

---

### Overview (`examples/vertx/README.md`)

# Containerize a [Eclipse Vert.x](https://vertx.io/) application with Jib

This is an example of how to easily build a Docker image for a [Eclipse Vert.x application](https://vertx.io/) with Jib.

```shell
./gradlew jibDockerBuild

docker run -d --rm -p 8080:8080 vertx-jib-example
```

## More information

Learn [more about Jib](https://github.com/GoogleContainerTools/jib).

Learn [more about Eclipse Vert.x](https://vertx.io).

---

### Overview (`jib-core/examples/README.md`)

# Jib Core examples

Please [file an issue](/../../issues/new) if you find any problems with the examples or would like to request other examples.

For examples on using Jib plugins, see [examples](../../examples).

### [sbt](https://index.scala-lang.org/schmitch/sbt-jib) plugin

Jib Core is used in a third-party project, [sbt-jib](https://github.com/schmitch/sbt-jib), that brings the benefits of Jib to [sbt](https://www.scala-sbt.org/) users.

### Cram

See [Cram](https://github.com/briandealwis/cram) for a simple example of a command-line utility that uses Jib Core to build Docker containers from file system contents.

### Using Jib Core in Gradle builds

See [build.gradle](build.gradle) for examples using Jib Core to build and manipulate container images within a `build.gradle` script.

### AutoJib - make your application self-containerize

See [AutoJib](https://github.com/coollog/autojib) for an example of a library that, when added as a dependency to a Java application, can make your application containerize itself.

---

### Overview (`proposals/archives/README.md`)

# Proposal Archives

This directory contains proposals that have already been implemented.

---

### Overview (`jib-core/examples/build.gradle/README.md`)

# Examples using Jib Core in Gradle builds

Jib Core is a containerization library for JVM languages, so it works well in Groovy as well. You can use Jib Core directly within a Gradle `build.gradle` to make tasks that build and manipulate container images.

For example, the following snippet is a simple example that creates a Gradle task that adds an environment variable to an existing image:

`build.gradle`:

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

### Configure Gcp Credentials (`docs/configure-gcp-credentials.md`)

# Configuring Credentials for [Google Container Registry (GCR)](https://cloud.google.com/container-registry/)

There are a few ways of supplying Jib with the credentials to push and pull images from your private GCR registry.

## Using the Docker credential helper

The easiest way is to install the [docker-credential-gcr](https://github.com/GoogleCloudPlatform/docker-credential-gcr).

### Installation

If you have [`gcloud` (Cloud SDK)](https://cloud.google.com/sdk/gcloud/) installed, you can run:

```shell
gcloud components install docker-credential-gcr
```

Alternatively, if you have `go get` installed, you can run:

```shell
go get -u github.com/GoogleCloudPlatform/docker-credential-gcr
```

Alternatively, you can download `docker-credential-gcr` from its [Github Releases](https://github.com/GoogleCloudPlatform/docker-credential-gcr/releases).

### Enable the Container Registry API

If you have not already done so, make sure you [enable the Container Registry API](https://console.cloud.google.com/flows/enableapi?apiid=containerregistry.googleapis.com&redirect=https://github.com/GoogleContainerRegistry/jib) for the Google Cloud Platform account you wish to use.

### Log in

Log in to the account you with to use with:

```shell
docker-credential-gcr gcr-login
```

This stores the credentials in `docker-credential-gcr`'s private credential store.

Now, you can use Jib to pull and push from images in the form `gcr.io/your-gcp-project/your-image-name`.

---

### Default Base Image (`docs/default_base_image.md`)

# Default Base Images in Jib

## Jib Build Plugins 3+

Starting from version 3.2, the default base image is the official [`eclipse-temurin`](https://hub.docker.com/_/eclipse-temurin) image on Docker Hub. Note that Eclipse Temurin by Adoptium is the [successor of AdoptOpenJDK](https://blog.adoptopenjdk.net/2021/08/goodbye-adoptopenjdk-hello-adoptium/). (For versions 3.0 and 3.1, the default is the official [`adoptopenjdk`](https://hub.docker.com/_/adoptopenjdk) image.)

For WAR projects, the default is the official [`jetty`](https://hub.docker.com/_/jetty) image on Docker Hub.

Note that Jib's default choice for Temurin, AdoptOpenJDK, and Jetty does not imply any endorsement to them. In fact, for strong reproducibility (which also results in better performance and efficiency), we always recommend configuring [`jib.from.image`](https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin#from-closure) (Gradle) or [`<from><image>`](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#from-object) (Maven) to pin to a specific base image using a digest (or at least a tag). And while doing so, you should do your due diligence to figure out which base image will work best for you.

### Docker Hub Download Rate Limit

Docker Hub enforces download rate limit. Because Jib pulls base images from Docker Hub, you can occasionally lead to the following error:
```
    > com.google.cloud.tools.jib.plugins.common.BuildStepsExecutionException: 429 Too Many Requests
      GET https://registry-1.docker.io/v2/library/adoptopenjdk/manifests/sha256:9db4a57b38b6d928761ec9c5a250677d306095df0f6a6bdd8936628e033b9f1a
      {
        "errors": [
          {
            "code": "TOOMANYREQUESTS",
            "message": "You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit"
          }
        ]
      }
```
Note that, even after Jib fully cached a base image, Jib still connects to Docker Hub to check the image every time it runs (unless you pin to a specific base image using a SHA digest). This is to check if the cached base image is up-to-date.

Some options:
* Configure a registry mirror.
* Prevent Jib from accessing Docker Hub (after Jib cached a base image locally).
   - Pin to a specific base image using a SHA digest (for example, `jib.from.image='eclipse-temurin:11-jre@sha256:...'`).
   - Do offline building.
   - Read a base from a local Docker daemon.
   - Set up a local registry, store a base image, and read it from the local registry.
* Retry with increasing backoffs.

See this [FAQ](https://github.com/GoogleContainerTools/jib/blob/master/docs/faq.md#i-am-hitting-docker-hub-rate-limits-how-can-i-configure-registry-mirrors) for more details about the options.

### Migration from Pre-3.0

Prior to 3.0, Jib Maven and Gradle plugins built images based on Distroless Java when the user didn't make an explicit choice. The Jib team carefully assessed all the surrounding factors and ultimately decided to switch from Distroless for the best interest of the Jib users. That is, to meet one of the core missions of Jib to build a secure and optimized image.

If you are already setting a specific base image, there will be absolutely no difference when you upgrade to 3.0. It will continue to use the base image you specified. Even if you are not specifying a base image, most likely upgrading to 3.0 will keep working fine, because it's just about getting a JRE from a different image. (But if you are not setting a base image, as we explained in the previous section, we highly recommend configuring it.)

For some reason if you have to keep the exact same behavior when using 3.0, you can always specify the Distroless Java as a base image.

* non-WAR projects
   ```groovy
   jib {
     from.image = 'gcr.io/distroless/java:11' // or ":8"
     ...
   }
   ```
   ```xml
     <configuration>
       <from><image>gcr.io/distroless/java:11</image></from> 
     </configuration>
   ```
   However, even when you decide to keep using Distroless, at least we strongly recommend `gcr.io/distroless/java-debian10:11`, because, as of Apr 2021, `gcr.io/distroless/java:{8,11}` is based on Debian 9 that reached end-of-life. (Note `gcr.io/distroless/java-debian10` doesn't have `:8`.)

* WAR projects
   ```gradle
   jib {
     from.image = 'gcr.io/distroless/java/jetty:java11' // or ":java8"
     container {
       entrypoint = 'INHERIT'
       appRoot = '/jetty/webapps/ROOT'
     }
     ...
   }
   ```
   ```xml
     <configuration>
       <from><image>gcr.io/distroless/java/jetty:java11</image></from> 
       <container>
         <entrypoint>INHERIT</entrypoint>
         <appRoot>/jetty/webapps/ROOT</appRoot>
       </container>
     </configuration>
   ```

## Jib CLI

For the JAR mode, Jib CLI versions prior to 0.8 have always used AdoptOpenJDK. Starting with 0.8, the tool uses [`eclipse-temurin`](https://hub.docker.com/_/eclipse-temurin). The WAR mode uses `jetty`.

---

### Faq (`docs/faq.md`)

## Frequently Asked Questions (FAQ)

If a question you have is not answered below, please [submit an issue](/../../issues/new).

| ☑️  Jib User Survey |
| :----- |
| What do you like best about Jib? What needs to be improved? Please tell us by taking a [one-minute survey](https://forms.gle/YRFeamGj51xmgnx28). Your responses will help us understand Jib usage and allow us to serve our customers (you!) better. |

[But, I'm not a Java developer.](#but-im-not-a-java-developer)\
[My build process doesn't let me integrate with the Jib Maven or Gradle plugin](#my-build-process-doesnt-let-me-integrate-with-the-jib-maven-or-gradle-plugin)\
[How do I run the image I built?](#how-do-i-run-the-image-i-built)\
[Where is bash?](#where-is-bash)\
[What image format does Jib use?](#what-image-format-does-jib-use)\
[Why is my image created 48+ years ago?](#why-is-my-image-created-48-years-ago)\
[Where is the application in the container filesystem?](#where-is-the-application-in-the-container-filesystem)\
[How are Jib applications layered?](#how-are-jib-applications-layered)\
[Can I learn more about container images?](#can-i-learn-more-about-container-images)\
[Which base image (JDK) does Jib use?](#which-base-image-jdk-does-jib-use)

**How-Tos**\
[How do I set parameters for my image at runtime?](#how-do-i-set-parameters-for-my-image-at-runtime)\
[Can I define a custom entrypoint?](#can-i-define-a-custom-entrypoint-at-runtime)\
[I want to containerize a JAR.](#i-want-to-containerize-a-jar)\
[I need to RUN commands like `apt-get`.](#i-need-to-run-commands-like-apt-get)\
[Can I ADD a custom directory to the image?](#can-i-add-a-custom-directory-to-the-image)\
[I need to add files generated during the build process to a custom directory on the image.](#i-need-to-add-files-generated-during-the-build-process-to-a-custom-directory-on-the-image)\
[Can I build to a local Docker daemon?](#can-i-build-to-a-local-docker-daemon)\
[How do I enable debugging?](#how-do-i-enable-debugging)\
[What would a Dockerfile for a Jib-built image look like?](#what-would-a-dockerfile-for-a-jib-built-image-look-like)\
[How can I inspect the image Jib built?](#how-can-i-inspect-the-image-jib-built)\
[I would like to run my application with a javaagent.](#i-would-like-to-run-my-application-with-a-javaagent)\
[How can I tag my image with a timestamp?](#how-can-i-tag-my-image-with-a-timestamp)\
[How do I specify a platform in the manifest list (or OCI index) of a base image?](#how-do-i-specify-a-platform-in-the-manifest-list-or-oci-index-of-a-base-image)\
[I want to exclude files from layers, have more fine-grained control over layers, change file ownership, etc.](#i-want-to-exclude-files-from-layers-have-more-fine-grained-control-over-layers-change-file-ownership-etc)\
[Jib build plugins don't have the feature that I need.](#jib-build-plugins-dont-have-the-feature-that-i-need)\
[I am hitting Docker Hub rate limits. How can I configure registry mirrors?](#i-am-hitting-docker-hub-rate-limits-how-can-i-configure-registry-mirrors)\
[Where is the global Jib configuration file and how I can configure it?](#where-is-the-global-jib-configuration-file-and-how-i-can-configure-it)

**Build Problems**\
[How can I diagnose problems pulling or pushing from remote registries?](#how-can-i-diagnose-problems-pulling-or-pushing-from-remote-registries)\
[What should I do when the registry responds with Forbidden or DENIED?](#what-should-i-do-when-the-registry-responds-with-forbidden-or-denied)\
[What should I do when the registry responds with UNAUTHORIZED?](#what-should-i-do-when-the-registry-responds-with-unauthorized)\
[How do I configure a proxy?](#how-do-i-configure-a-proxy)\
[How can I examine network traffic?](#how-can-i-examine-network-traffic)\
[How do I view debug logs for Jib?](#how-do-i-view-debug-logs-for-jib)\
[I am seeing `Method Not Found` or `Class Not Found` errors when building.](#i-am-seeing-method-not-found-or-class-not-found-errors-when-building)\
[I am seeing `Unsupported class file major version` when building.](#i-am-seeing-unsupported-class-file-major-version-when-building)\
[I am seeing `NoClassDefFoundError: com/github/luben/zstd/ZstdOutputStream` when building.](#i-am-seeing-noclassdeffounderror-comgithublubenzstdzstdoutputstream-when-building)

**Launch Problems**\
[I am seeing `ImagePullBackoff` on my pods.](#i-am-seeing-imagepullbackoff-on-my-pods-in-minikube)\
[Why won't my container start?](#why-wont-my-container-start)

**Jib CLI**\
[How does the `jar` command support Standard JARs?](#how-does-the-jar-command-support-standard-jars)\
[How does the `jar` command support Spring Boot JARs?](#how-does-the-jar-command-support-spring-boot-jars)\
[How does the `war` command work?](#how-does-the-war-command-work)

---

### But, I'm not a Java developer.

Check out [Jib CLI](https://github.com/GoogleContainerTools/jib/tree/master/jib-cli), a general-purpose command-line tool for building containers images from filesystem content.

Also see [rules_docker](https://github.com/bazelbuild/rules_docker) for a similar existing container image build tool for the [Bazel build system](https://github.com/bazelbuild/bazel). The tool can build images for languages such as Python, NodeJS, Java, Scala, Groovy, C, Go, Rust, and D.

### My build process doesn't let me integrate with the Jib Maven or Gradle plugin

The [Jib CLI](https://github.com/GoogleContainerTools/jib/tree/master/jib-cli) can be useful for users with complex build workflows that make it hard to integrate the Jib Maven or Gradle plugin. It is a standalone application that is powered by [Jib Core](https://github.com/GoogleContainerTools/jib/tree/master/jib-core) and offers two commands:

* [Build](https://github.com/GoogleContainerTools/jib/tree/master/jib-cli#build-command): Builds images from the filesystem content.
 
* [Jar](https://github.com/GoogleContainerTools/jib/tree/master/jib-cli#jar-command): Examines your JAR and builds an image with optimized layers or containerizes the JAR as-is.

Check out the [Jib CLI section](#jib-cli) of the FAQ for more information.

### How do I run the image I built?

If you built your image directly to the Docker daemon using `jib:dockerBuild` (Maven) or `jibDockerBuild` (Gradle), you simply need to use `docker run <image name>`.

If you built your image to a registry using `jib:build` (Maven) or `jib` (Gradle), you will need to pull the image using `docker pull <image name>` before using `docker run`.

To run your image on Kubernetes, you can use kubectl:

```shell
kubectl run jib-deployment --image=<image name>
```

For more information, see [steps 4-6 of the Kubernetes Engine deployment tutorial](https://cloud.google.com/kubernetes-engine/docs/tutorials/hello-app#step_4_create_a_container_cluster).

### Where is bash?

By default, Jib Maven and Gradle plugin versions prior to 3.0 used [`distroless/java`](https://github.com/GoogleContainerTools/distroless/tree/master/java) as the base image, which did not have a shell program (such as `sh`, `bash`, or `dash`). However, recent Jib tools use [default base images](default_base_image.md) that come with shell programs: Adoptium Eclipse Temurin (formerly AdoptOpenJDK) and Jetty for WAR projects.

Note that you can always set a different base image. Jib's default choice for Temurin or AdoptOpenJDK does not imply any endorsement to it; you should do your due diligence to choose the right image that works best for you. Also note that the default base image is unpinned (the tag can point to different images over time), so we recommend configuring a base image with a SHA digest for strong reproducibility.

* Configuring a base image in Maven
   ```xml
   <configuration>
     <from>
       <image>openjdk:11-jre-slim@sha256:...</image>
     </from>
   </configuration>
   ```

* Configuring a base image in Gradle
   ```groovy
   jib.from.image = 'openjdk:11-jre-slim@sha256:...'
   ```

* Configuring a base image in Jib CLI
   ```
   $ jib jar --from openjdk:11-jre-slim@sha256:... --target ... app.jar
   ```

### What image format does Jib use?

Jib currently builds into the [Docker V2.2](https://docs.docker.com/registry/spec/manifest-v2-2/) image format or [OCI image format](https://github.com/opencontainers/image-spec).

#### Maven

See [Extended Usage](../jib-maven-plugin#extended-usage) for the `<container><format>` configuration.

#### Gradle

See [Extended Usage](../jib-gradle-plugin#extended-usage) for the `container.format` configuration.

### Why is my image created 48+ years ago?

For reproducibility purposes, Jib sets the creation time of the container images to the Unix epoch (00:00:00, January 1st, 1970 in UTC). If you would like to use a different timestamp, set the `jib.container.creationTime` / `<container><creationTime>` parameter to an ISO 8601 date-time. You may also use the value `USE_CURRENT_TIMESTAMP` to set the creation time to the actual build time, but this sacrifices reproducibility since the timestamp will change with every build.

<details>
<summary>Setting <code>creationTime</code> parameter (click to expand)</summary>
<p>

#### Maven

```xml
<configuration>
  <container>
    <creationTime>2019-07-15T10:15:30+09:00</creationTime>
  </container>
</configuration>
```

#### Gradle

```groovy
jib.container.creationTime = '2019-07-15T10:15:30+09:00'
```

</p>
</details>

Note that the modification time of the files in the built image put by Jib will still be 1 second past the epoch. The file modification time can be configured using [`<container><filesModificationTime>`](../jib-maven-plugin#container-object) (Maven) or [`jib.container.filesModificationTime`](../jib-gradle-plugin#container-closure) (Gradle).

#### Please tell me more about reproducibility!

_Reproducible_ means that given the same inputs, a build should produce the same outputs.  Container images are uniquely identified by a digest (or a hash) of the image contents and image metadata.  Tools and infrastructure such the Docker daemon, Docker Hub, registries, Kubernetes, etc) treat images with different digests as being different.

To ensure that a Jib build is reproducible — that the rebuilt container image has the same digest — Jib adds files and directories in a consistent order, and sets consistent creation- and modification-times and permissions for all files and directories.  Jib also ensures that the image metadata is recorded in a consistent order, and that the container image has a consistent creation time.  To ensure consistent times, files and directories are recorded as having a creation and modification time of 1 second past the Unix Epoch (1970-01-01 00:00:01.000 UTC), and the container image is recorded as being created on the Unix Epoch.  Setting `container.creationTime` to `USE_CURRENT_TIMESTAMP` and then rebuilding an image will produce a different timestamp for the image creation time, and so the container images will have different digests and appear to be different.

For more details see [reproducible-builds.org](https://reproducible-builds.org).

### Where is the application in the container filesystem?

Jib packages your Java application into the following paths on the image:

* `/app/libs/` contains all the dependency artifacts
* `/app/resources/` contains all the resource files
* `/app/classes/` contains all the classes files
* the contents of the extra directory (default `src/main/jib`) are placed relative to the container's root directory (`/`)

### How are Jib applications layered?

Jib makes use of [layering](https://containers.gitbook.io/build-containers-the-hard-way/#layers) to allow for fast rebuilds - it will only rebuild the layers containing files that changed since the previous build and will reuse cached layers containing files that didn't change. Jib organizes files in a way that groups frequently changing files separately from large, rarely changing files. For example, `SNAPSHOT` dependencies are placed in a separate layer from other dependencies, so that a frequently changing `SNAPSHOT` will not force the entire dependency layer to rebuild itself.

Jib applications are split into the following layers:

* All other dependencies
* Snapshot dependencies
* Project dependencies
* Resources
* Classes
* Each extra directory (`jib.extraDirectories` in Gradle, `<extraDirectories>` in Maven) builds to its own layer

### Which base image (JDK) does Jib use?

[`eclipse-temurin`](https://hub.docker.com/_/eclipse-temurin) by Adoptium (formerly [`adoptopenjdk`](https://hub.docker.com/_/adoptopenjdk)) and [`jetty`](https://hub.docker.com/_/jetty) (for WAR). See [Default Base Images in Jib](default_base_image.md) for details.

### Can I learn more about container images?

If you'd like to learn more about container images, [@coollog](https://github.com/coollog) has a guide: [Build Containers the Hard Way](https://containers.gitbook.io/build-containers-the-hard-way/), which takes a deep dive into everything involved in getting your code into a container and onto a container registry.


## Configuring Jib

### How do I set parameters for my image at runtime?

#### JVM Flags

For the default base image, you can use the `JAVA_TOOL_OPTIONS` environment variable (note that other JRE images may require using other environment variables):

Using Docker: `docker run -e "JAVA_TOOL_OPTIONS=<JVM flags>" <image name>`

Using Kubernetes:
```yaml
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: <name>
    image: <image name>
    env:
    - name: JAVA_TOOL_OPTIONS
      value: <JVM flags>
```
Note that many JVMs may only support a max length of **1024** characters for the `JAVA_TOOL_OPTIONS` environment variable, and anything longer than this may be cut off by the JVM.

For Java 9+, often you may want to use [`JDK_JAVA_OPTIONS`](https://stackoverflow.com/questions/52986487/what-is-the-difference-between-jdk-java-options-and-java-tool-options-when-using) instead of `JAVA_TOOL_OPTIONS`.

#### Other Environment Variables

Using Docker: `docker run -e "NAME=VALUE" <image name>`

Using Kubernetes:
```yaml
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: <name>
    image: <image name>
    env:
    - name: NAME
      value: VALUE
```

#### Arguments to Main

Using Docker: `docker run <image name> <arg1> <arg2> <arg3>`

Using Kubernetes:
```yaml
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: <name>
    image: <image name>
    args:
    - <arg1>
    - <arg2>
    - <arg3>
```

For more information, see the [`JAVA_TOOL_OPTIONS` environment variable](https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/envvars002.html), the [`docker run -e` reference](https://docs.docker.com/engine/reference/run/#env-environment-variables), and [defining environment variables for a container in Kubernetes](https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/).

### Can I define a custom entrypoint at runtime?

Normally, the plugin sets a default entrypoint for java applications, or lets you configure a custom entrypoint using the `container.entrypoint` configuration parameter. You can also override the default/configured entrypoint by defining a custom entrypoint when running the container. See [`docker run --entrypoint` reference](https://docs.docker.com/engine/reference/run/#entrypoint-default-command-to-execute-at-runtime) for running the image with Docker and overriding the entrypoint command, or see [Define a Command and Arguments for a Container](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/) for running the image in a [Kubernetes](https://kubernetes.io/) Pod and overriding the entrypoint command.

### <a name="i-want-to-containerize-an-executable-jar"></a>I want to containerize a JAR.

The intention of Jib is to add individual class files, resources, and dependency JARs into the container instead of putting a JAR. This lets Jib choose an opinionated, optimal layout for the application on the container image, which also allows it to skip the extra JAR-packaging step.

However, you can set `<containerizingMode>packaged` (Maven) or `jib.containerizingMode = 'packaged'` (Gradle) to containerize a JAR, but note that your application will always be run via `java -cp ... your.MainClass` (even if it is an executable JAR). Some disadvantages of setting `containerizingMode='packaged'`:

- You need to run the JAR-packaging step (`mvn package` in Maven or the `jar` task in Gradle).
- Reduced granularity in building and caching: if any of your Java source files or resource files are updated, not only the JAR has to be rebuilt, but the entire layer containing the JAR in the image has to be recreated and pushed to the destination.
- If it is a fat or shaded JAR embedding all dependency JARs, you are duplicating the dependency JARs in the image. Worse, it results in far more reduced granularity in building and caching, as dependency JARs can be huge and all of them need to be pushed repeatedly even if they do not change.

Note that for runnable JARs/WARs, currently Jib does not natively support creating an image that runs a JAR (or WAR) through `java -jar runnable.jar` (although it is not impossible to configure Jib to do so at the expense of more complex project setup.)

### I need to RUN commands like `apt-get`.

Running commands like `apt-get` slows down the container build process. We **do not recommend or support** running commands as part of the build.

However, if you need to run commands, you can build a custom image and configure Jib to use it as the base image.

<details>
<summary>Base image configuration examples (click to expand)</summary>
<p>

#### Maven

In [`jib-maven-plugin`](../jib-maven-plugin), you can then use this custom base image by adding the following configuration:

```xml
<configuration>
  <from>
    <image>custom-base-image</image>
  </from>
</configuration>
```

#### Gradle

In [`jib-gradle-plugin`](../jib-gradle-plugin), you can then use this custom base image by adding the following configuration:

```groovy
jib.from.image = 'custom-base-image'
```
</p>
</details>

### Can I ADD a custom directory to the image?

Yes, using the _extra directories_ feature. See the [Maven](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#adding-arbitrary-files-to-the-image) and [Gradle](https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin#adding-arbitrary-files-to-the-image) docs for examples.

### I need to add files generated during the build process to a custom directory on the image.

If the current extra directories design doesn't meet your needs (e.g. you need to set up the extra files directory with files generated during the build process), you can use additional goals/tasks to create the extra directory as part of your build.

<details>
<summary>File copying examples (click to expand)</summary>
<p>

#### Maven

In Maven, you can use the `maven-resources-plugin` to copy files to your extra directory. For example, if you generate files in `target/generated/files` and want to add them to `/my/files` on the container, you can add the following to your `pom.xml`:

```xml
<plugins>
  ...
  <plugin>
    <artifact>jib-maven-plugin</artifact>
    ...
    <configuration>
      <extraDirectories>
        <paths>
          <path>${project.basedir}/target/extra-directory/</path>
        </paths>
      </extraDirectories>
    </configuration>
  </plugin>
  ...
  <plugin>
    <artifact>maven-resources-plugin</artifact>
    <version>3.2.0</version>
    <configuration>
      <outputDirectory>${project.basedir}/target/extra-directory/my/files</outputDirectory>
      <resources>
        <resource>
          <directory>${project.basedir}/target/generated/files</directory>
        </resource>
      </resources>
    </configuration>
  </plugin>
  ...
</plugins>
```

The `copy-resources` goal will run automatically before compile, so if you are copying files from your build output to the extra directory, you will need to either set the life-cycle phase to `post-compile` or later, or run the goal manually:

```sh
mvn compile resources:copy-resources jib:build
```

#### Gradle

The same can be accomplished in Gradle by using a `Copy` task. In your `build.gradle`:

```groovy
jib.extraDirectories.paths = ['build/extra-directory']

task setupExtraDir(type: Copy) {
  from file('build/generated/files')
  into file('build/extra-directory/my/files')
}
tasks.jib.dependsOn setupExtraDir
```

The files will be copied to your extra directory when you run the `jib` task.

</p>
</details>

### Can I build to a local Docker daemon?

There are several ways of doing this:

- Use [`jib:dockerBuild` for Maven](../jib-maven-plugin#build-to-docker-daemon) or [`jibDockerBuild` for Gradle](../jib-gradle-plugin#build-to-docker-daemon) to build directly to your local Docker daemon.
- Use [`jib:buildTar` for Maven](../jib-maven-plugin#build-an-image-tarball) or [`jibBuildTar` for Gradle](../jib-gradle-plugin#build-an-image-tarball) to build the image to a tarball, then use `docker load --input` to load the image into Docker (the tarball built with these commands will be located in `target/jib-image.tar` for Maven and `build/jib-image.tar` for Gradle by default).
- [`docker pull`](https://docs.docker.com/engine/reference/commandline/pull/) the image built with Jib to have it available in your local Docker daemon.
- Alternatively, instead of using a Docker daemon, you can run a local container registry, such as [Docker registry](https://docs.docker.com/registry/deploying/) or other repository managers, and point Jib to push to the local registry.

### How do I enable debugging?

Use the [`JAVA_TOOL_OPTIONS`](#how-do-i-set-parameters-for-my-image-at-runtime) to pass along debugging configuration arguments.  For example, to have the remote VM accept local debug connections on port 5005, but not suspend:
```
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=localhost:5005
```

Then connect your debugger to port 5005 on your local host.  You can port-forward the container port to a localhost port for easy access.

Using Docker: `docker run -p 5005:5005 <image>`

Using Kubernetes: `kubectl port-forward <pod name> 5005:5005`

Beware: in Java 8 and earlier, specifying only a port meant that the JDWP socket was open to all incoming connections which is insecure.  It is recommended to limit the debug port to localhost.


### I would like to run my application with a javaagent.

You can run your container with a javaagent by placing it somewhere in the `src/main/jib/myfolder` directory to add it to the container's filesystem, then pointing to it using Jib's `container.jvmFlags` configuration.

#### Maven

```xml
<configuration>
  <container>
    <jvmFlags>
      <jvmFlag>-javaagent:/myfolder/agent.jar</jvmFlag>
    </jvmFlags>    
  </container>
</configuration>
```

#### Gradle

```groovy
jib.container.jvmFlags = ['-javaagent:/myfolder/agent.jar']
```

See also:
- [Can I ADD a custom directory to the image?](#can-i-add-a-custom-directory-to-the-image)
- [Javaagent sample](https://github.com/GoogleContainerTools/jib/tree/master/examples/java-agent): dynamically downloads a javaagent during build
- (Gradle) [javaagent-gradle-plugin](https://github.com/ryandens/javaagent-gradle-plugin#jib-integration): third-party Jib extension

### How can I tag my image with a timestamp?

#### Maven

To tag the image with a simple timestamp, add the following to your `pom.xml`:

```xml
<properties>
  <maven.build.timestamp.format>yyyyMMdd-HHmmssSSS</maven.build.timestamp.format>
</properties>
```

Then in the `jib-maven-plugin` configuration, set the `tag` to:

```xml
<configuration>
  <to>
    <image>my-image-name:${maven.build.timestamp}</image>
  </to>
</configuration>
```

You can then use the same timestamp to reference the image in other plugins.

#### Gradle

To tag the image with a timestamp, simply set the timestamp as the tag for `to.image` in your `jib` configuration. For example:

```groovy
jib.to.image = 'gcr.io/my-gcp-project/my-app:' + System.nanoTime()
```


### What would a Dockerfile for a Jib-built image look like?

A Dockerfile that performs a Jib-like build is shown below:

```Dockerfile
# Jib uses Adoptium Eclipse Temurin (formerly AdoptOpenJDK).
FROM eclipse-temurin:11-jre

# Multiple copy statements are used to break the app into layers,
# allowing for faster rebuilds after small changes
COPY dependencyJars /app/libs
COPY snapshotDependencyJars /app/libs
COPY projectDependencyJars /app/libs
COPY resources /app/resources
COPY classFiles /app/classes

# Jib's extra directory ("src/main/jib" by default) is used to add extra, non-classpath files
COPY src/main/jib /

# Jib's default entrypoint when container.entrypoint is not set
ENTRYPOINT ["java", jib.container.jvmFlags, "-cp", "/app/resources:/app/classes:/app/libs/*", jib.container.mainClass]
CMD [jib.container.args]
```

When unset, Jib will infer the value for `jib.container.mainClass`.

Some plugins, such as the [Docker Prepare Gradle Plugin](https://github.com/gclayburg/dockerPreparePlugin), will even automatically generate a Docker context for your project, including a Dockerfile.

### How can I inspect the image Jib built?

To inspect the image that is produced from the build using Docker, you can use commands such as `docker inspect your/image:tag` to view the image configuration, or you can also download the image using `docker save` to manually inspect the container image. Other tools, such as [dive](https://github.com/wagoodman/dive), provide nicer UI to inspect the image.

### How do I specify a platform in the manifest list (or OCI index) of a base image?

Newer Jib versions added an _incubating feature_ that provides support for selecting base images with the desired platforms from a manifest list. For example,

```xml
  <from>
    <image>... image reference to a manifest list ...</image>
    <platforms>
      <platform>
        <architecture>amd64</architecture>
        <os>linux</os>
      </platform>
      <platform>
        <architecture>arm64</architecture>
        <os>linux</os>
      </platform>
    </platforms>
  </from>
```

```gradle
jib.from {
  image = '... image reference to a manifest list ...'
  platforms {
    platform {
      architecture = 'amd64'
      os = 'linux'
    }
    platform {
      architecture = 'arm64'
      os = 'linux'
    }
  }
}
```

The default when not specified is a single "amd64/linux" platform, whose behavior is backward-compatible.

When multiple platforms are specified, Jib creates and pushes a manifest list (also known as a fat manifest) after building and pushing all the images for the specified platforms.

As an incubating feature, there are certain limitations:
- OCI image indices are not supported (as opposed to Docker manifest lists).
- Only `architecture` and `os` are supported. If the base image manifest list contains multiple images with the given architecture and os, the first image will be selected.
- Does not support using a local Docker daemon or tarball image for a base image.
- Does not support pushing to a Docker daemon (`jib:dockerBuild` / `jibDockerBuild`) or building a local tarball (`jib:buildTar` / `jibBuildTar`).

Make sure to specify a manifest _list_ in `<from><image>` (whether by a tag name or a digest (`@sha256:...`)). For troubleshooting, you may want to check what platforms the manifest list contains. To view a manifest list, [enable experimental docker CLI](https://docs.docker.com/engine/reference/commandline/cli/#experimental-features) features and then run the [manifest inspect](https://docs.docker.com/engine/reference/commandline/manifest_inspect/) command.

```
$ docker manifest inspect openjdk:8
{         
   ...
   // This confirms that openjdk:8 points to a manifest list.
   "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
   "manifests": [
      {
         // This entry in the list points to the manifest for the ARM64/Linux manifest.
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         ...
         "digest": "sha256:1fbd49e3fc5e53154fa93cad15f211112d899a6b0c5dc1e8661d6eb6c18b30a6",
         "platform": {
            "architecture": "arm64",
            "os": "linux",
            "variant": "v8"
         }
      }
   ]
}
```

### I want to exclude files from layers, have more fine-grained control over layers, change file ownership, etc.

See ["Jib build plugins don't have the feature that I need"](#jib-build-plugins-dont-have-the-feature-that-i-need).

### Jib build plugins don't have the feature that I need.

The Jib build plugins have an extension framework that enables anyone to easily extend Jib's behavior to their needs. We maintain select [first-party](https://github.com/GoogleContainerTools/jib-extensions/tree/master/first-party) plugins for popular use cases like [fine-grained layer control](https://github.com/GoogleContainerTools/jib-extensions/tree/master/first-party/jib-layer-filter-extension-gradle) and [Quarkus support](https://github.com/GoogleContainerTools/jib-extensions/tree/master/first-party/jib-quarkus-extension-gradle), but anyone can write and publish an extension. Check out the [jib-extensions](https://github.com/GoogleContainerTools/jib-extensions) repository for more information.

### I am hitting Docker Hub rate limits. How can I configure registry mirrors?

See the [Maven](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#global-jib-configuration), [Gradle](https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin#global-jib-configuration) or [Jib CLI](https://github.com/GoogleContainerTools/jib/blob/master/jib-cli/README.md#global-jib-configuration) docs. Note that the example in the docs uses [Google's Docker Hub mirror on `mirror.gcr.io`](https://cloud.google.com/container-registry/docs/pulling-cached-images).

Starting from Jib build plugins 3.0, Jib by default uses [base images on Docker Hub](default_base_image.md), so you may start to encounter the rate limits if you are not explicitly setting a base image.

Some other alternatives to get around the rate limits:

* Prevent Jib from accessing Docker Hub (after Jib cached a base image locally).
   - **Pin to a specific base image using a SHA digest.** For example, `jib.from.image='eclipse-temurin:11-jre@sha256:...'`. If you are not setting a base image with a SHA digest (which is the case if you don't set `jib.from.image` at all), then every time Jib runs, it reaches out to the registry to check if the base image is up-to-date. On the other hand, if you pin to a specific image with a digest, then the image is immutable. Therefore, if Jib has cached the image once (by running Jib online once to fully cache the image), Jib will not reach out to the Docker Hub. See [this Stack Overflow answer](https://stackoverflow.com/a/61190005/1701388) for more details.
   - (Maven/Gradle plugins only) **Do offline building.** Pass `--offline` to Maven or Gradle. Before that, you need to run Jib online once to cache the image. However, `--offline` means you cannot push to a remote registry. See [this Stack Overflow answer](https://stackoverflow.com/a/61190005/1701388) for more details.
   - **Retrieve a base image from a local Docker daemon.** Store an image to your local Docker daemon, and set, say, `jib.from.image='docker://eclipse-temurin:11-jre'`. It can be slow for an initial build where Jib has to cache the image in Jib's format. For performance reasons, we usually recommend using an image on a registry.
   - **Set up a local registry, store a base image, and read it from the local registry.** Setting up a local registry is as simple as running `docker run -d -p5000:5000 registry:2`, but nevertheless, the whole process is a bit involved.
* Retry with increasing backoffs. For example, using the [`retry`](https://github.com/kadwanev/retry) tool.

### Where is the global Jib configuration file and how I can configure it?

See the [Maven](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#global-jib-configuration), [Gradle](https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin#global-jib-configuration) or [Jib CLI](https://github.com/GoogleContainerTools/jib/blob/master/jib-cli/README.md#global-jib-configuration) docs.


## Build Problems

### <a name="registry-errors"></a>How can I diagnose problems pulling or pushing from remote registries?

There are a few reasons why Jib may be unable to connect to a remote registry, including:

- **Registry reports FORBIDDEN.** See [_What should I do when the registry responds with Forbidden or DENIED?_](#what-should-i-do-when-the-registry-responds-with-forbidden-or-denied)
- **Registry reports UNAUTHORIZED.** See [_What should I do when the registry responds with UNAUTHORIZED?_](#what-should-i-do-when-the-registry-responds-with-unauthorized)
- **Access requires a proxy.** See [_How do I configure a proxy?_](#how-do-i-configure-a-proxy) for details.
- **The registry does not support HTTPS.** We do not pass authentication details on non-HTTPS connections, though this can be overridden with the `sendCredentialsOverHttp` system property, but it is not recommend  (_version 0.9.9_).
- **The registry's SSL certificates have expired or are not trusted.**  We have a separate document on [handling registries that use self-signed certificates](self_sign_cert.md), which may also apply if the SSL certificate is signed by an untrusted Certificate Authority.  Jib supports an  `allowInsecureRegistries` flag to ignore SSL certificate validation, but it is not recommend (_version 0.9.9_).
- **The registry does not support the [Docker Image Format V2 Schema 2](https://github.com/GoogleContainerTools/jib/issues/601)** (sometimes referred to as _v2-2_).  This problem is usually shown by failures wth `INVALID_MANIFEST` errors. Some registries can be configured to support V2-2 such as [Artifactory](https://www.jfrog.com/confluence/display/RTF/Docker+Registry#DockerRegistry-LocalDockerRepositories) and [OpenShift](https://docs.openshift.com/container-platform/3.9/install_config/registry/extended_registry_configuration.html#middleware-repository-acceptschema2). Other registries, such as Quay.io/Quay Enterprise, are in the process of adding support.


### What should I do when the registry responds with Forbidden or DENIED?

If the registry returns `403 Forbidden` or `"code":"DENIED"`, it often means Jib successfully authenticated using your credentials but the credentials do not have permissions to pull or push images. Make sure your account/role has the permissions to do the operation.

Depending on registry implementations, it is also possible that the registry actually meant you are not authenticated. See [What should I do when the registry responds with UNAUTHORIZED?](#what-should-i-do-when-the-registry-responds-with-unauthorized) to ensure you have set up credentials correctly.

### What should I do when the registry responds with UNAUTHORIZED?

If the registry returns `401 Unauthorized` or `"code":"UNAUTHORIZED"`, it is often due to credential misconfiguration. Examples:

* You did not configure auth information in the default places where Jib searches. (See also [Authentication Methods](https://github.com/GoogleContainerTools/jib/blob/master/jib-maven-plugin/README.md#authentication-methods)).

   - Docker credential file (as generated by `docker login` or `podman login`) at
     - `$XDG_RUNTIME_DIR/containers/auth.json`, `$XDG_CONFIG_HOME/containers/auth.json` or `$HOME/.config/containers/auth.json`
     - `$DOCKER_CONFIG/config.json`
     - `$HOME/.docker/config.json`

     This is [one of the configuration files](https://docs.docker.com/engine/reference/commandline/cli/#configuration-files) for the `docker` or `podman` command line tool. See [configuration files document](https://docs.docker.com/engine/reference/commandline/cli/#configuration-files), [credential store](https://docs.docker.com/engine/reference/commandline/login/#credentials-store) and [credential helper](https://docs.docker.com/engine/reference/commandline/login/#credential-helpers) sections, and [this](https://github.com/GoogleContainerTools/jib/issues/101) for how to configure auth. For example, you can do `docker login` to save auth in `config.json`, but it is often recommended to configure a credential helper (also configurable in `config.json`).

     If Jib was able to retrieve auth information from a Docker credential file, you should see a log message similar to `Using credentials from Docker config (/home/myuser/.docker/config.json)` where you can verify which credential file was picked up by Jib.

   - Jib configurations

      - Configuring credential helpers: [`<from/to><credHelper>`](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#using-docker-credential-helpers) (Maven) / [`from/to.credHelper`](https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin#using-docker-credential-helpers) (Gradle)
      - Specific credentials (not recommend): [`<from/to><auth><username>/<password>`](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#using-specific-credentials) or in [`settings.xml`](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#using-maven-settings) (Maven) / [`from/to.auth.username/password`](https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin#using-specific-credentials) (Gradle)
      - These parameters can also be set through properties: [Maven](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#system-properties) / [Gradle](https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin#system-properties)

* For Google Cloud Registry (GCR), the Container Registry API is not yet enabled for your project.
   - You enable the API from [Cloud Console](https://console.cloud.google.com/flows/enableapi?apiid=containerregistry.googleapis.com) or with the following [Cloud SDK](https://cloud.google.com/sdk/docs) command: `gcloud services enable containerregistry.googleapis.com`

* `$HOME/.docker/config.json` may also contain short-lived authorizations in the `auths` block that may have expired. In the case of Google Container Registry, if you had previously used `gcloud docker` to configure these authorizations, you should remove these stale authorizations by editing your `config.json` and deleting lines from `auths` associated with `gcr.io` (for example: `"https://asia.gcr.io"`). You can then run `gcloud auth configure-docker` to correctly configure the `credHelpers` block for more robust interactions with gcr.

* Different auth configurations exist in multiple places, and Jib is not picking up the auth information you are working on.

* You configured a credential helper, but the helper is not on `$PATH`. This is especially common when running Jib inside IDE where the IDE binary is launched directly from an OS menu and does not have access to your shell's environment.

* Configured credentials have access to the base image repository but not to the target image repository (or vice versa).

* Typos in username, password, image names, repository names, or registry names. This is a very common error.

* Image names do not conform to the structure or policy that a registry requires. For example, [Docker Hub returns 401 Unauthorized](https://github.com/GoogleContainerTools/jib/issues/2650#issuecomment-667323777) when trying to use a multi-level repository name.

* Incorrect port number in image references (`registry.hostname:<port>/...`).

* You are using a private registry without HTTPS. See [How can I diagnose problems pulling or pushing from remote registries?](#how-can-i-diagnose-problems-pulling-or-pushing-from-remote-registries).

Note, if Jib was able to retrieve credentials, you should see a log message like these:

```
Using credentials from Docker config (/home/user/.docker/config.json) for localhost:5000/java
```
```
Using credential helper docker-credential-gcr for gcr.io/project/repo
```
```
Using credentials from Maven settings file for gcr.io/project/repo
```
```
Using credentials from <from><auth> for gcr.io/project/repo
```
```
Using credentials from to.auth for gcr.io/project/repo
```

If you encounter issues interacting with a registry other than `UNAUTHORIZED`, check ["How can I diagnose problems pulling or pushing from remote registries?"](#how-can-i-diagnose-problems-pulling-or-pushing-from-remote-registries).

### How do I configure a proxy?

Jib currently requires configuring your build tool to use the appropriate [Java networking properties](https://docs.oracle.com/javase/8/docs/api/java/net/doc-files/net-properties.html) (`https.proxyHost`, `https.proxyPort`, `https.proxyUser`, `https.proxyPassword`).


### How can I examine network traffic?

It can be useful to examine network traffic to diagnose connectivity issues. Jib uses the Google HTTP client library to interact with registries which logs HTTP requests using the JVM-provided `java.util.logging` facilities.  It is very helpful to serialize Jib's actions using the `jib.serialize` property.

To see the HTTP traffic, create a `logging.properties` file with the following:
```
handlers = java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=ALL

# CONFIG hides authentication data
# ALL includes authentication data
com.google.api.client.http.level=CONFIG
```

And then launch your build tool as follows:
```sh
mvn --batch-mode -Djava.util.logging.config.file=path/to/logging.properties -Djib.serialize=true ...
```
or
```sh
gradle --no-daemon --console=plain --info -Djava.util.logging.config.file=path/to/logging.properties -Djib.serialize=true ...
```

**Note**: Jib Gradle plugins prior to version 2.2.0 have an issue generating HTTP logs ([#2356](https://github.com/GoogleContainerTools/jib/issues/2356)).

You may want to enable the debug logs too (`-X` for Maven, or `--debug --stacktrace` for Gradle).

When configured correctly, you should see logs like this:
```
Mar 31, 2020 9:55:52 AM com.google.api.client.http.HttpResponse <init>
CONFIG: -------------- RESPONSE --------------
HTTP/1.1 202 Accepted
Content-Length: 0
Docker-Distribution-Api-Version: registry/2.0
Docker-Upload-Uuid: 6292f0d7-93cb-4a8e-8336-78a1bf7febd2
Location: https://registry-1.docker.io/v2/...
Range: 0-657292
Date: Tue, 31 Mar 2020 13:55:52 GMT
Strict-Transport-Security: max-age=31536000

Mar 31, 2020 9:55:52 AM com.google.api.client.http.HttpRequest execute
CONFIG: -------------- REQUEST  --------------
PUT https://registry-1.docker.io/v2/...
Accept:
Accept-Encoding: gzip
Authorization: <Not Logged>
User-Agent: jib 2.1.1-SNAPSHOT jib-maven-plugin Google-HTTP-Java-Client/1.34.0 (gzip)
```

### How do I view debug logs for Jib?

Maven: use `mvn -X -Djib.serialize=true` to enable more detailed logging and serialize Jib's actions.

Gradle: use `gradle --debug -Djib.serialize=true` to enable more detailed logging and serialize Jib's actions.

### I am seeing `Method Not Found` or `Class Not Found` errors when building.

Sometimes when upgrading your Gradle build plugin versions, you may experience errors due to mismatching versions of dependencies pulled in (for example: [issues/2183](https://github.com/GoogleContainerTools/jib/issues/2183)). This can be due to the buildscript classpath loading behavior described [on gradle forums](https://discuss.gradle.org/t/version-is-root-build-gradle-buildscript-is-overriding-subproject-buildscript-dependency-versions/20746/3). 

This commonly appears in multi module Gradle projects. A solution to this problem is to define all of your plugins in the base project and apply them selectively in your subprojects as needed. This should help alleviate the problem of the buildscript classpath using older versions of a library.

`build.gradle` (root)
```groovy
plugins {
  id 'com.google.cloud.tools.jib' version 'x.y.z' apply false
}
```

`build.gradle` (sub-project)
```groovy
plugins {
  id 'com.google.cloud.tools.jib'
}
```

### I am seeing `Unsupported class file major version` when building.

When you're using latest Java versions to write an app (or using an old version of Jib), you may see the error _coming from Jib when building an image_ (not when compiling your code):

```
Failed to execute goal com.google.cloud.tools:jib-maven-plugin:3.2.0:dockerBuild (default-cli) on project demo: Execution default-cli of goal com.google.cloud.tools:jib-maven-plugin:3.2.0:dockerBuild failed: Unsupported class file major version 61
```

Jib uses the [ASM library](https://asm.ow2.io/) to examine compiled Java bytecode to automatically infer a main class (in other words, the class that defines `public static void main()` to start your app). In this way, if you have only one such class, Jib can automatically infer and use that class to set an image entrypoint (basically, a command to start your app). When new Java versions come out, often the ASM library version used in Jib doesn't support the new bytecode format. If this is the case, check if you are using the latest Jib. If you still get the error with the latest Jib, file a [bug](https://github.com/GoogleContainerTools/jib/issues/new/choose) to have the Jib team upgrade the ASM library.

**Workaround**: to prevent Jib from doing auto-inference, you can manually set your desired main class via [`<container><mainClass>`](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#container-object) (for example, `<container><mainClass>com.example.your.Main</mainClass>`). As with other Jib parameters, it can be set through system/Maven properties or on the command-line (for example, `-Dcontainer.mainClass=...`).

Note that although the ASM library is the common cause of this error coming from Jib, it may be due to other reasons. Always check the full stack (`-e` or `-X` for Maven and `--stacktrace` for Gradle) to see where the error is coming from.

### I am seeing `NoClassDefFoundError: com/github/luben/zstd/ZstdOutputStream` when building.

Jib supports base image layers with media-type `application/vnd.oci.image.layer.v1.tar+zstd`, i.e. compressed with zstd algorithm instead of gzip.

However, the dependency to zstd is optional, so pulling such layers will result in:

```
java.lang.NoClassDefFoundError: com/github/luben/zstd/ZstdOutputStream
at org.apache.commons.compress.compressors.zstandard.ZstdCompressorOutputStream.<init>
```

This can be solved by adding a dependency to artifact `com.github.luben:zstd-jni:1.5.2-3` to the plugin.

## Launch problems

### I am seeing `ImagePullBackoff` on my pods (in [minikube](https://github.com/kubernetes/minikube)).

When you use your private image built with Jib in a [Kubernetes cluster](kubernetes.io), the cluster needs to be configured with credentials to pull the image. This involves 1) creating a [Secret](https://kubernetes.io/docs/concepts/configuration/secret/), and 2) using the Secret as [`imagePullSecrets`](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account).

```shell
kubectl create secret docker-registry registry-json-key \
  --docker-server=<registry> \
  --docker-username=<username> \
  --docker-password=<password> \
  --docker-email=<any valid email address>

kubectl patch serviceaccount default \
  -p '{"imagePullSecrets":[{"name":"registry-json-key"}]}'
```

For example, if you are using GCR, the commands would look like (see [Advanced Authentication Methods](https://cloud.google.com/container-registry/docs/advanced-authentication)):

```shell
kubectl create secret docker-registry gcr-json-key \
  --docker-server=https://gcr.io \
  --docker-username=_json_key \
  --docker-password="$(cat keyfile.json)" \
  --docker-email=any@valid.com

kubectl patch serviceaccount default \
  -p '{"imagePullSecrets":[{"name":"gcr-json-key"}]}'
```

See more at [Using Google Container Registry (GCR) with Minikube](https://ryaneschinger.com/blog/using-google-container-registry-gcr-with-minikube/).

### Why won't my container start?

There are some common reasons why containers fail on launch.

#### My shell script won't run.

Jib Maven and Gradle plugins prior to 3.0 used Distroless Java as the default base image, which does not have a shell. See [Where is bash?](#where-is-bash) for more details.

#### The container fails with `exec` errors.

A Jib user reported an error launching their container:
```
standard_init_linux.go:211 exec user process caused "no such file or directory"
```

On examining the container structure with [Dive](https://github.com/wagoodman/dive), the user discovered that the contents of the `/lib` directory had disappeared.

The user had used Jib's ability to install extra files into the image ([Maven](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#adding-arbitrary-files-to-the-image), [Gradle](https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin#adding-arbitrary-files-to-the-image)) to install a library file by placing it in `src/main/jib/lib/libfoo.so`. This would normally cause the `libfoo.so` to be installed in the image as `/lib/libfoo.so`. But `/lib` and `/lib64` in the user's base image were symbolic links. Jib does not follow such symbolic links when creating the image. And at container initialization time, Docker treats these symlinks as a file, and thus the symbolic link was replaced with `/lib` as a new directory. As a result, none of the system shared libraries were resolved and dynamically-linked programs failed.

Solution: The user installed the file in a different location.

## Jib CLI 
 
### How does the `jar` command support Standard JARs?

The Jib CLI supports both [thin JARs](https://docs.oracle.com/javase/tutorial/deployment/jar/downman.html) (where dependencies are specified in the JAR's manifest) and fat JARs.

The current limitation of using a fat JAR is that the embedded dependencies will not be placed into the designated dependencies layers. They will instead be placed into the classes or resources layer. Therefore, for efficiency, we recommend against containerizing fat JARs (Spring Boot fat JARs are an [exception](#how-does-the-jar-command-support-spring-boot-jars)) if you can prepare thin JARs. We hope to have better support for fat JARs in the future.

A standard JAR can be containerized by the `jar` command in two modes, exploded or packaged. 

#### Exploded Mode (Recommended)

Achieved by calling `jib jar --target ${TARGET_REGISTRY} ${JAR_NAME}.jar`

The default mode for containerizing a JAR. It will open up the JAR and optimally place files into the following layers:  

* Other Dependencies Layer
* Snapshot-Dependencies Layer
* Resources Layer
* Classes Layer

**Entrypoint** : `java -cp /app/dependencies/:/app/explodedJar/ ${MAIN_CLASS}`

#### Packaged Mode

Achieved by calling `jib jar --target ${TARGET_REGISTRY} ${JAR_NAME}.jar --mode packaged`.

It will result in the following layers on the container:

* Dependencies Layer
* Jar Layer

**Entrypoint** : `java -jar ${JAR_NAME}.jar`

### How does the `jar` command support Spring Boot JARs?

The `jar` command currently supports containerization of Spring Boot fat JARs.
A Spring-Boot fat JAR can be containerized in two modes, exploded or packaged. 

#### Exploded Mode (Recommended)

Achieved by calling `jib jar --target ${TARGET_REGISTRY} ${JAR_NAME}.jar`

The default mode for containerizing a JAR. It will respect [`layers.idx`](https://spring.io/blog/2020/08/14/creating-efficient-docker-images-with-spring-boot-2-3) in the JAR (if present) or create optimized layers in the following format:

* Other Dependencies Layer
* Spring-Boot-Loader Layer
* Snapshot-Dependencies Layer
* Resources Layer
* Classes Layer

**Entrypoint** : `java -cp /app org.springframework.boot.loader.JarLauncher`

#### Packaged Mode

Achieved by calling `jib jar --target ${TARGET_REGISTRY} ${JAR_NAME}.jar --mode packaged`

It will containerize the JAR as is. However, **note** that we highly recommend against using packaged mode for containerizing Spring Boot fat JARs. 

**Entrypoint**: `java -jar ${JAR_NAME}.jar`

### How does the `war` command work?

The `war` command currently supports containerization of standard WARs. It uses the official [`jetty`](https://hub.docker.com/_/jetty) on Docker Hub as the default base image and explodes out the WAR into `/var/lib/jetty/webapps/ROOT` on the container. It creates the following layers:

* Other Dependencies Layer
* Snapshot-Dependencies Layer
* Resources Layer
* Classes Layer

The default entrypoint when using a jetty base image will be `java -jar /usr/local/jetty/start.jar --module=ee10-deploy` unless you choose to specify a custom one.

You can use a different Servlet engine base image with the help of the `--from` option and customize `--app-root`, `--entrypoint` and `--program-args`. If you don't set the `entrypoint` or `program-arguments`, Jib will inherit them from the base image. However, setting the `--app-root` is **required** if you use a non-jetty base image. Here is how the `war` command may look if you're using a Tomcat image:
```
 $ jib war --target=<image-reference> myapp.war --from=tomcat:8.5-jre8-alpine --app-root=/usr/local/tomcat/webapps/ROOT
```

---

### Google Cloud Build (`docs/google-cloud-build.md`)

# Jib on Google Cloud Build

You can use Jib on [Google Cloud Build](https://cloud.google.com/build) in a simple step:

```yaml
steps:
  - name: 'gcr.io/cloud-builders/javac:8'
    entrypoint: './gradlew'
    args: ['--console=plain', '--no-daemon', ':server:jib', '-Djib.to.image=gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA']
```

Any Java container can be used for building, not only the `gcr.io/cloud-builders/javac:*` (from [gcr.io/cloud-builders/javac](https://github.com/GoogleCloudPlatform/cloud-builders/tree/master/javac)), for example with [Temurin](https://adoptium.net/en-GB/temurin/)'s:

```yaml
steps:
  - name: 'docker.io/library/eclipse-temurin:25'
    entrypoint: './gradlew'
    args: ['--console=plain', '--no-daemon', ':server:jib', '-Djib.to.image=gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA']
```

To use [Google "Distroless" Container Images](https://github.com/GoogleContainerTools/distroless) to build with Jib on Google Cloud Build, and avoid running into `Step #1: standard_init_linux.go:228: exec user process caused: no such file or directory` errors (because Google's _distroless_ containers are based on `busybox`), you have to do something like this:

```yaml
steps:
  - name: 'gcr.io/distroless/java17-debian11:debug'
    entrypoint: '/busybox/sh'
    args:
      - -c
      - |
        ln -s /busybox/sh /bin/sh
        ln -s /busybox/env /usr/bin/env
        /workspace/gradlew --console=plain --no-daemon --gradle-user-home=/home/.gradle :server:jib -Djib.to.image=gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA
```

---

### Privacy (`docs/privacy.md`)

The privacy of our users is very important to us.
Your use of this software is subject to the <a href=https://policies.google.com/privacy>Google Privacy Policy</a>.

## Update check
Many Jib users are unaware of new releases. To encourage users to stay up-to-date, the Jib Maven and Jib Gradle plugins (2.0.0 and later) and Jib CLI (0.6.0 and later) will
periodically check to see if there is a new version of Jib is available. This check fetches a simple text
file hosted in Google Cloud Storage. As a side effect this request is logged, which includes the request path,
source IP address, and the user-agent string. The user-agent is set by Jib and includes the Jib tool name
and version.

### How to disable update checks

1. set the `jib.disableUpdateChecks` system property to `true`
2. set `disableUpdateCheck` to `true` in Jib's global config. The global config is in the following locations by default:
    * Linux: `$XDG_CONFIG_HOME/google-cloud-tools-java/jib/config.json` (if `$XDG_CONFIG_HOME` is defined), else `$HOME/.config/google-cloud-tools-java/jib/config.json`
    * Mac: `$XDG_CONFIG_HOME/Google/Jib/config.json` (if `$XDG_CONFIG_HOME` is defined), else `$HOME/Library/Preferences/Google/Jib/config.json`
    * Windows: `$XDG_CONFIG_HOME\Google\Jib\Config\config.json` (if `$XDG_CONFIG_HOME` is defined), else `%LOCALAPPDATA%\Google\Jib\Config\config.json`

---

### Self Sign Cert (`docs/self_sign_cert.md`)

# Accessing a private docker registry with self-signed certificate

Jib relies on the Java Runtime Environment's list of approved _Certification Authority Certificates_ for validating SSL certificates, and will hence fail when connecting to a docker registry that uses a self-signed `https` certificate.  This document describes two approaches for handling registries with self-signed certificates.  Both approaches configure the JRE's list of approved CA Certificates.

These CA Certificates for JRE are managed through a type of a keystore file called _truststore_. An easy way to manipulate truststores is using the [KeyStore Explorer](http://keystore-explorer.org/), an open source GUI replacement for the Java command-line  `keytool` and `jarsigner` utilities. Download and install KeyStore Explorer from the [official website](http://keystore-explorer.org/downloads.html).


## Step 1. Identify Java runtime used by build tool

We must first identify the location of your build-tool's JRE's list of CA Certificates.

### Maven

Run `mvn --version` and take note of the Java runtime location:

```shell
$ mvn --version
Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-18T06:33:14+12:00)
Maven home: /usr/local/Cellar/maven/3.5.4/libexec
Java version: 1.8.0_172, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre
Default locale: en_NZ, platform encoding: UTF-8
OS name: "mac os x", version: "10.13.6", arch: "x86_64", family: "mac"
```

In this example the Java runtime location is `/Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre`.

### Gradle

Create an init script with the following:

```
println org.gradle.internal.jvm.Jvm.current().getJavaHome()
```

And run `gradle -I /path/to/script` to output the executing JRE location.

```shell
$ gradle -I /tmp/printjrelocation
/Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home

> Task :help 

Welcome to Gradle 4.6.
[...]
```

### JRE vs JDK Distributions

The Maven and Gradle examples above report two different directories, where the Maven example reported a `.../jre` subdirectory.  Java Development Kits usually include a standalone Java Runtime Environment inside the `jre/` directory.  If present, use the `jre/` directory as the runtime location.

## 2. Load JRE CA Certificates

Having identified your Java runtime location:

* Launch `KeyStore Explorer`
* Select _Open an existing KeyStore_
* Navigate to the Java runtime location identified previously, and then continue to open the file at `jre/lib/security/cacerts`.  If there is no `jre/` directory then this is a JRE distribution and should navigate and instead open the file at `lib/security/cacerts`.
  * In the example above, this file would be `/Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre/lib/security/cacerts`.
* You will likely be prompted for a password. The default password for the `cacerts` file is `changeit`.

## 3. Import Self-Signed Certificate

If you have the self-signed certificate in a file then:

* Select _Tools > Import Trusted Certificate_
* Select the certifcate file on disk
* Give it a name, or use suggested name, and click _OK_
* Click _OK_ on the success window

Otherwise use _Examine > Examine SSL_ to connect to your service and click the _Import_ button to import its SSL certificate. Then click _OK_.



## 4. Save the CA Certificates

Now we save the updated truststore. We can either save to a new truststore and configure our build's JVM to use this new truststore, or modify the JRE's list of CA Certificates.

#### Option 1: Create a New Truststore

This option creates a _new_ list of CA Certificates and configures your build tool to use this new list as the JRE's list of approved CA certificates.

Within _KeyStore Explorer_, select _File > Save As..._ and save the new truststore file as a _JKS_ file within your project location. You will be prompted for a password; we use `password` in the examples below.

##### Maven

The following snippet shows how to configure Maven to use this new truststore file:

```shell
$ ./mvnw -Djavax.net.ssl.trustStore=path/to/truststore.jks \
  -Djavax.net.ssl.trustStorePassword=password \
  -Dimage=<host>:<port>/<image> jib:build
```

##### Gradle

The following snippet shows how to configure Gradle to use this new truststore file:

```shell
$ ./gradlew jib \
  -Djavax.net.ssl.trustStore=path/to/truststore.jks \
  -Djavax.net.ssl.trustStorePassword=password
```

#### Option 2: Modify the JRE `cacerts`

The other approach modifies the JRE's list of CA Certificates to include the registry's self-signed certificate.  The certificate will be trusted at the JRE level, affecting all Java applications running on it. You must re-import the certificate when you update to a new JRE.

Basically you instruct KeyStore Explorer to save your modified `cacerts` and replace what was previously configured with the JRE.  Depending on your operating system and permissions, you may need to save to a new file and then replace the original `lib/security/cacerts` file with administrative privileges.

---

--- METRICS ---
- Files Extracted: 25
- Estimated Token Budget: ~50120 tokens
- Canonical Reference: https://codewiki.google/github.com/GoogleContainerTools/jib
